Как использовать flask-sqlalchemy с существующей моделью sqlalchemy?

Я прочитал flask-sqlalchemy или sqlalchemy, в котором рекомендуется использовать flask-sqlalchemy с flask. Я хочу следовать этому подходу.

Однако у меня есть существующая модель, написанная для сценариев командной строки, которая основана на declarative_base sqlalchemy, например,

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()   # create sqlalchemy Base class
              :
class Runner(Base):
    etc.

Я хочу по-прежнему иметь возможность использовать сценарии командной строки с этой моделью, но также хочу создать веб-приложение на основе этой модели.

Есть ли способ расширить существующую модель, чтобы получить преимущества от использования расширения flask-sqlalchemy? Или я должен просто свернуть свой собственный и использовать ScopedSession sqlalchemy?


person Lou K    schedule 01.10.2013    source источник
comment
не будет ли проблемой переписать сценарии командной строки, используя модель flask-sqlalchemy?   -  person Paolo Casciello    schedule 01.10.2013
comment
Я не знаю - раньше не использовал флягу или фляжную алхимию и не знаю побочных эффектов. Нужно ли переписывать сценарии или просто импортировать модель? Я также должен был упомянуть, что я использовал перегонный куб для отслеживания изменений в базе данных на случай возникновения проблем с совместимостью.   -  person Lou K    schedule 01.10.2013
comment
Обновление 2020: это может быть многообещающим способом решения этой проблемы: stackoverflow.com/questions/28789063/   -  person Joe    schedule 15.10.2020


Ответы (1)


В настоящее время это не очень хорошо поддерживается, но не невозможно сделать. См. эту проблему в списке проблем Flask-SQLAlchemy, в котором признается, что текущая реализация расширения делает эту ситуацию более головной болью, чем они думают. Надеюсь, в будущем это будет лучше поддерживаться (после того, как будет определен надежный путь миграции и новый API).

Эта проблема дает следующий пример кода:

from flask import Flask
from models import Base, User # Your non-Flask-SQLAlchemy models...
from flask_sqlalchemy import SQLAlchemy

app =  Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)

@app.before_first_request
def setup():
    # Recreate database each time for demo
    Base.metadata.drop_all(bind=db.engine)
    Base.metadata.create_all(bind=db.engine)
    db.session.add(User('Bob Jones', '[email protected]'))
    db.session.add(User('Joe Quimby', '[email protected]'))
    db.session.commit()

@app.route('/')
def root():
    users = db.session.query(User).all()
    return u"<br>".join([u"{0}: {1}".format(user.name, user.email) for user in users])

if __name__ == '__main__':
    app.run('127.0.0.1', 5000) 

Здесь следует отметить несколько вещей:

Во-первых, вы теряете возможность выполнять User.query (поскольку User был создан с использованием собственной декларативной базы), а также все другие вещи, которые Flask-SQLAlchemy db.Model дает вам (например, возможность автоматически генерировать имена таблиц и методы, такие как first_or_404()).

Во-вторых, каждый раз, когда вам нужно выполнить действия, связанные с метаданными (например, drop_all или create_all), вы не можете использовать методы Flask-SQLAlchemy. Вы должны использовать исходные метаданные, привязанные к движку Flask-SQLAlchemy.

Я не пробовал это сам, поэтому я не уверен, есть ли какие-либо другие ошибки в этом подходе. Возможно, вы захотите принять участие в этом билете, если найдете его.

person Mark Hildreth    schedule 01.10.2013
comment
Спасибо за указание на проблему. Я могу провести эксперимент, но определенно проще, если вы знаете этот ответ: если я перепишу модель, используя db.model flask-alchemy, а не Base, с тем, чтобы сломать сценарии командной строки? - person Lou K; 03.10.2013
comment
@Lou_K: Вероятно, это не поломка как таковая, но когда вы пытаетесь запустить их, вам, возможно, придется выполнить дополнительную работу по настройке приложения Flask, прежде чем можно будет запустить основную часть сценария. - person Mark Hildreth; 03.10.2013
comment
@Mark_Hildreth: я мог бы попробовать это. Если это станет обременительным, возможно, я смогу заставить тот же исходный файл работать для модели, но зависеть от некоторой информации об окружающей среде (какой-то конфигурации, внешней по отношению к python, установленной в командной строке или веб-приложении), чтобы импортировать нужные вещи, и объявите Base соответствующим образом в зависимости от того, используется ли он сценарием командной строки или приложением flask. Хотя выглядит не очень элегантно. И это нужно тщательно продумать, чтобы убедиться, что две системы каким-то образом не сталкиваются друг с другом. - person Lou K; 04.10.2013