Как правильно использовать Flask-SQLAlchemy на сервере Flask? - PullRequest
0 голосов
/ 30 октября 2018

Это код модели, я тестировал этот код, он не содержит ошибок и может создавать таблицы, записи в БД

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'

1 Ответ

0 голосов
/ 01 ноября 2018

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

вы создаете экземпляр Flask с именем app и передаете его конструктору SQLAlchemy, присваивающему результат переменной db (вы фактически делаете это дважды, когда импортируете createdb из app.py ). Ключевым моментом является то, что 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.run() в app.py не вызывается на app, о котором знает createdb.db.

...