Reputation: 3785
Is this just part of the debugging process with Flask? Is this because the Flask server is reading into a file that it is writing to? Am I not closing connections properly?
From what I can gather errno(9) indicates:
(bad file number), when the file descriptor you are using is not valid. Either the file descriptor refers to no open file, or a read (or write) request is made to a file that is open only for writing (or reading). If you are doing socket programming, the socket descriptor has got closed before you could do any operation on that and you may end up with this error.
I am using Virtualenv 15.1.0, Python 3.6.0 and Flask 0.12 &
$ pip freeze
appdirs==1.4.2
click==6.7
Flask==0.12
itsdangerous==0.24
Jinja2==2.9.5
MarkupSafe==0.23
packaging==16.8
pyparsing==2.1.10
requests==2.13.0
six==1.10.0
Werkzeug==0.11.15
This is the code I am writing which invokes the error upon exiting the server:
from flask import Flask, render_template, request, jsonify
import sqlite3
app = Flask(__name__)
connection = sqlite3.connect('database.db')
connection.execute('CREATE TABLE IF NOT EXISTS films (title TEXT, rating INTEGER)')
connection.close() <------------------ IMPROPER CLOSURE?
@app.route('/')
def index():
return render_template("base.html")
@app.route('/movie', methods = ['POST'])
def add_movie_function():
connection = sqlite3.connect('database.db')
cursor = connection.cursor()
title = request.form['title']
rating = request.form['rating']
try:
query = 'INSERT INTO films (title, rating) VALUES (?, ?)'
cursor.execute(query, (title, rating))
connection.commit()
message = 'Successfully inserted title and rating data into movies table!'
except:
connection.rollback()
message = 'There was an issue with inserting data into the movies table :('
finally:
connection.close() <------------------ IMPROPER CLOSURE?
return message
@app.route('/movies', methods = ['GET'])
def list_all_movies():
connection = sqlite3.connect('database.db')
cursor = connection.cursor()
try:
cursor.execute('SELECT * FROM films')
connection.commit()
search_result = jsonify(cursor.fetchall())
except:
search_result = 'An error occured getting all the film titles'
finally:
connection.close() <------------------ IMPROPER CLOSURE?
return search_result
app.run(debug = True)
...and this is the full traceback:
(venv) 66 Wed Mar 08 15:29:11$ export FLASK_APP=simpleFlaskAPI.py
(venv) 67 Wed Mar 08 15:42:08$ flask run
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger pin code: 230-157-201
127.0.0.1 - - [08/Mar/2017 15:42:21] "GET /movies HTTP/1.1" 200 -
^C * Serving Flask app "simpleFlaskAPI"
Traceback (most recent call last):
File "/Users/username/python/lesson4/python-minicamp-homework-4/venv/bin/flask", line 11, in <module>
sys.exit(main())
File "/Users/username/python/lesson4/python-minicamp-homework-4/venv/lib/python3.6/site-packages/flask/cli.py", line 507, in main
cli.main(args=args, prog_name=name)
File "/Users/username/python/lesson4/python-minicamp-homework-4/venv/lib/python3.6/site-packages/flask/cli.py", line 374, in main
return AppGroup.main(self, *args, **kwargs)
File "/Users/username/python/lesson4/python-minicamp-homework-4/venv/lib/python3.6/site-packages/click/core.py", line 697, in main
rv = self.invoke(ctx)
File "/Users/username/python/lesson4/python-minicamp-homework-4/venv/lib/python3.6/site-packages/click/core.py", line 1066, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/Users/username/python/lesson4/python-minicamp-homework-4/venv/lib/python3.6/site-packages/click/core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/Users/username/python/lesson4/python-minicamp-homework-4/venv/lib/python3.6/site-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/Users/username/python/lesson4/python-minicamp-homework-4/venv/lib/python3.6/site-packages/click/decorators.py", line 64, in new_func
return ctx.invoke(f, obj, *args[1:], **kwargs)
File "/Users/username/python/lesson4/python-minicamp-homework-4/venv/lib/python3.6/site-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/Users/username/python/lesson4/python-minicamp-homework-4/venv/lib/python3.6/site-packages/flask/cli.py", line 432, in run_command
use_debugger=debugger, threaded=with_threads)
File "/Users/username/python/lesson4/python-minicamp-homework-4/venv/lib/python3.6/site-packages/werkzeug/serving.py", line 708, in run_simple
inner()
File "/Users/username/python/lesson4/python-minicamp-homework-4/venv/lib/python3.6/site-packages/werkzeug/serving.py", line 670, in inner
fd=fd)
File "/Users/username/python/lesson4/python-minicamp-homework-4/venv/lib/python3.6/site-packages/werkzeug/serving.py", line 564, in make_server
passthrough_errors, ssl_context, fd=fd)
File "/Users/username/python/lesson4/python-minicamp-homework-4/venv/lib/python3.6/site-packages/werkzeug/serving.py", line 474, in __init__
socket.SOCK_STREAM)
File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/socket.py", line 460, in fromfd
nfd = dup(fd)
OSError: [Errno 9] Bad file descriptor
If this is abnormal, should I file a bug report with the folks of Flask?
Thank you!
UPDATE per Pipskweak's suggestions, I have modified the script:
from flask import Flask, render_template, request, jsonify
import sqlite3
app = Flask(__name__)
connection = sqlite3.connect('database.db')
connection.execute('CREATE TABLE IF NOT EXISTS films (title TEXT, rating INTEGER)')
connection.close()
@app.route('/')
def index():
return render_template("base.html")
@app.route('/movie', methods = ['POST'])
def add_movie_function():
data = None
try:
connection = sqlite3.connect('database.db')
with connection:
cursor = connection.cursor()
title = request.form['title']
rating = request.form['rating']
query = 'INSERT INTO films (title, rating) VALUES (?, ?)'
data = cursor.execute(query, (title, rating))
connection.commit()
message = 'Successfully inserted title and rating data into movies table!'
except sqlite3.Error as e:
if connection:
connection.rollback()
message = 'There was an issue with inserting data into the movies table :('
raise ValueError('sqlite3: {}'.format(e))
finally:
if connection:
connection.close()
print(message)
if data:
print(data)
return message
@app.route('/movies', methods = ['GET'])
def list_all_movies():
data = None
try:
connection = sqlite3.connect('database.db')
with connection:
cursor = connection.cursor()
data = cursor.execute('SELECT * FROM films')
connection.commit()
search_result = jsonify(cursor.fetchall())
except sqlite3.Error as e:
if connection:
search_result = 'An error occured getting all the film titles'
raise ValueError('sqlite3: {}'.format(e))
finally:
if connection:
connection.close()
print(search_result)
if data:
print(data)
return search_result
app.run(debug = True)
# if __name__ == '__main__':
# print('__name__ == "__main__"')
# app.run(debug = True)
OF NOTE: using the if __name_ == ...
does not invoke debugger mode in Flask when invoking flask by export FLASK_APP...
and flask run
. Using python3 scriptname.py
with the if name == main
, however, does invoke debugger - so I suspect something is amiss with Flask here?
AND I also adjusted the script to run in python 2 (only a couple print statements and the except sqlite3.Error, e:
syntax) and tried running it in Flask (using debugger mode) using virtual environment and the python script works fine with the html and when I quit out of the Flask server, no OSError: [Errno 9] Bad file descriptor. So, is this a bug I should report to the Flask folks?
FWIW:
$ pip freeze
appdirs==1.4.3
click==6.7
Flask==0.12
itsdangerous==0.24
Jinja2==2.9.5
MarkupSafe==1.0
packaging==16.8
pyparsing==2.2.0
requests==2.13.0
six==1.10.0
Werkzeug==0.11.15
Perhaps this is a similar issue?
Upvotes: 1
Views: 3800
Reputation:
So, the try
, except
, finally
statement might be causing some issues.
Did you want to give this a shot? It's a little more specific on the exceptions and closing the connection.
def query_db(sql_statement):
try:
# connect to database
conn = sqlite3.connect('database.db')
with conn:
cur = conn.cursor()
data = cur.execute(sql_statement)
# commit the changes
conn.commit()
except sqlite3.Error, e:
# if an error has occured, rollback the changes
if conn:
conn.rollback()
# print the error out. Probably useful.
raise ValueError('sqlite3: {}'.format(e))
finally:
# lastly, close the database, probably a good idea.
if conn:
conn.close()
if data:
return data
Also, your missing the if
statement before app.run()
if __name__ == "__main__":
app.run(debug=True)
Upvotes: 1