【问题标题】:What is correct way to use Flask-SQLAlchemy in Flask server?在 Flask 服务器中使用 Flask-SQLAlchemy 的正确方法是什么?
【发布时间】:2018-10-30 10:35:32
【问题描述】:

这是模型代码,我测试过这个代码,没有错误,可以在DB中创建表,记录

createdb.py

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:@localhost:3306/ai'
db = SQLAlchemy(app)

if __name__ == 'createdb':
    db.reflect()
    db.drop_all()
    db = SQLAlchemy(app)

class Class(db.Model):
    id = db.Column(db.Integer, primary_key=True, unique=True, autoincrement=True)
    label = db.Column(db.String(255), unique=True, nullable=False)

    def __init__(self, label):
        self.label = label

    def __repr__(self):
        return '<Class %r>' % self.username

class Photo(db.Model):
    id = db.Column(db.Integer, primary_key=True, unique=True, autoincrement=True)
    path = db.Column(db.String(1024), nullable=False)

    def __init__(self, path):
        self.path = path

    def __repr__(self):
        return '<Photo %r>' % self.username

class PhotoClass(db.Model):
    id = db.Column(db.Integer, primary_key=True, unique=True, autoincrement=True)
    photoId = db.Column(db.Integer, db.ForeignKey('photo.id'), nullable=False)
    classId = db.Column(db.Integer, db.ForeignKey('class.id'), nullable=False)
    score = db.Column(db.Float, nullable=False)

    def __init__(self, photoId, classId):
        self.photoId = photoId
        self.classId = classId

    def __repr__(self):
        return '<PhotoClass %r>' % self.username

if __name__ == 'createdb':
    db.create_all()
    db.session.add(Class('Plain'))
    db.session.add(Class('Printed'))
    db.session.commit()

这是服务器代码

app.py

import createdb

app = Flask(__name__)

@app.route('/')
def index():
    createdb.db.session.add(createdb.Class('aaa'))
    createdb.db.session.commit()
    return render_template('index.html')

if __name__ == '__main__':
    app.run()

如果我导入到服务器,仍然没有错误,当我去 localhost:5000 时,我会得到这个错误

track_modifications = app.config['SQLALCHEMY_TRACK_MODIFICATIONS']
KeyError: 'SQLALCHEMY_TRACK_MODIFICATIONS'

这是完全错误

[2018-10-30 18:31:03,288] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
  File "C:\python\lib\site-packages\sqlalchemy\util\_collections.py", line 999, in __call__
    return self.registry[key]
KeyError: 12344

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\python\lib\site-packages\flask\app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\python\lib\site-packages\flask\app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\python\lib\site-packages\flask\app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\python\lib\site-packages\flask\_compat.py", line 35, in reraise
    raise value
  File "C:\python\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\python\lib\site-packages\flask\app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "E:\0\airbtn\yeetungaiserver\app.py", line 17, in index
    createdb.db.session.add(createdb.Class('aaa'))
  File "C:\python\lib\site-packages\sqlalchemy\orm\scoping.py", line 153, in do
    return getattr(self.registry(), name)(*args, **kwargs)
  File "C:\python\lib\site-packages\sqlalchemy\util\_collections.py", line 1001, in __call__
    return self.registry.setdefault(key, self.createfunc())
  File "C:\python\lib\site-packages\sqlalchemy\orm\session.py", line 2950, in __call__
    return self.class_(**local_kw)
  File "C:\python\lib\site-packages\flask_sqlalchemy\__init__.py", line 142, in __init__
    track_modifications = app.config['SQLALCHEMY_TRACK_MODIFICATIONS']
KeyError: 'SQLALCHEMY_TRACK_MODIFICATIONS'

【问题讨论】:

  • 请输入完整的错误堆栈跟踪。是哪条线路造成的?提到了哪个文件堆栈跟踪?

标签: python flask sqlalchemy flask-sqlalchemy


【解决方案1】:

createdb.py:

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:@localhost:3306/ai'
db = SQLAlchemy(app)

if __name__ == 'createdb':
    db.reflect()
    db.drop_all()
    db = SQLAlchemy(app)

您创建一个名为appFlask 实例,并将其传递给SQLAlchemy 构造函数,将结果分配给变量db(实际上,当您从app.py 导入createdb 时,您会执行此操作两次)。他们的关键点是db 被实例化引用Flask 实例createdb.app

然后在 app.py 中:

import createdb  # createdb.app is created upon import

app = Flask(__name__)  # but you create a new `Flask` instance called app

@app.route('/')
def index():
    # all of the below db operations occur on createdb.db which is in the 
    # createdb.app context, not the context of app created in this module
    createdb.db.session.add(createdb.Class('aaa'))
    createdb.db.session.commit()
    return render_template('index.html')

if __name__ == '__main__':
    # the app you run here, isn't the app that was made available to db in 
    # in createdb.py. It has no idea what db is!
    app.run()
    # try createdb.app.run()

我已经在上面对您的 app.py 代码进行了更详细的注释,但不足之处在于 app.py 中的 app.run() 调用不会在 createdb.db 知道的 app 上调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-25
    • 2015-03-14
    • 1970-01-01
    相关资源
    最近更新 更多