退出Flask服务器引发" OSError:[Errno 9]错误的文件描述符"当app.run(debug = True)

时间:2017-03-08 20:55:35

标签: python-3.x sockets debugging flask

这只是Flask调试过程的一部分吗?这是因为Flask服务器正在读取它正在写入的文件吗?我没有正确关闭连接吗?

what I can gather errno(9)表示:

  

(错误的文件编号),当您使用的文件描述符无效时。文件描述符指的是没有打开文件,或者对仅为写入(或读取)打开的文件发出读取(或写入)请求。   如果你正在进行套接字编程,那么套接字描述符已经关闭,然后你可以对它进行任何操作,你可能会得到这个错误。

我使用的是Virtualenv 15.1.0,Python 3.6.0和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

这是我写的代码,它在退出服务器时调用错误:

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)

......这是完整的追溯:

(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

如果这是异常的,我应该向Flask的人提交错误报告吗?

谢谢!

根据Pipskweak的建议更新,我修改了脚本:

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注意:在if __name_ == ...export FLASK_APP...调用flask时,使用flask run不会在Flask中调用调试器模式。然而,将python3 scriptname.pyif name == main一起使用会调用调试器 - 所以我怀疑Flask在这里有什么不妥之处?

我还调整了脚本以在python 2中运行(只有几个打印语句和except sqlite3.Error, e:语法)并尝试使用虚拟环境在Flask(使用调试器模式)中运行它,并且python脚本可以正常工作html,当我退出Flask服务器时,没有OSError:[Errno 9]错误的文件描述符。那么,这是一个我应该向Flask人报告的错误吗?

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?

1 个答案:

答案 0 :(得分:1)

因此,tryexceptfinally语句可能会导致一些问题。

你想拍这个吗?它对异常和关闭连接有点具体。

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

另外,您错过了if

之前的app.run()声明
if __name__ == "__main__":
    app.run(debug=True)