What is correct way to use Flask-SQLAlchemy in Flask server?

回眸只為那壹抹淺笑 提交于 2021-02-08 11:39:40

问题


This is model code, I have tested this code, it is no error and it can create tables, records in 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()

This is server code

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()

If I import to server, it is still no error, when I go to localhost:5000, I will get this error

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

This is full error

[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'

回答1:


In 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)

you create an instance of Flask called app and pass that to the SQLAlchemy constructor assigning the result to the variable, db (you actually do this twice when you import createdb from app.py). They key point is that db is instantiated referencing the Flask instance createdb.app.

Then in 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()

I've annotated your app.py code above with more detail but the short of it is that the app.run() call in app.py isn't called on the app that createdb.db is aware of.



来源:https://stackoverflow.com/questions/53062408/what-is-correct-way-to-use-flask-sqlalchemy-in-flask-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!