¿Cómo usar flask-sqlalchemy con el modelo sqlalchemy existente?

He leído flask-sqlalchemy o sqlalchemy que recomienda el uso de flask-sqlalchemy con flask. Quiero seguir este enfoque.

Sin embargo, tengo un modelo existente escrito para los guiones de línea de comandos que se basa en la base declarativa de sqlalchemy, por ejemplo,

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

Quiero poder seguir utilizando los guiones de línea de comandos con este modelo, pero también quiero crear una aplicación web alrededor del modelo.

¿Hay una manera de extender el modelo existente, para obtener el beneficio de usar la extensión flask-sqlalchemy? ¿O debería simplemente rodar la mía y usar ScopedSession de sqlalchemy?

Actualmente, esto es algo que no está bien soportado, pero no imposible de hacer. Vea este problema en la lista de problemas de Flask-SQLAlchemy, que admite que la implementación actual de la extensión hace que esta situación sea más dolorosa de lo que creen. Esperamos que esto sea mejor soportado en el futuro (una vez que se determine una ruta de migración sólida y una nueva API).

Ese problema da el siguiente ejemplo de código:

 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', 'bob@gmail.com')) db.session.add(User('Joe Quimby', 'eat@joes.com')) db.session.commit() @app.route('/') def root(): users = db.session.query(User).all() return u"
".join([u"{0}: {1}".format(user.name, user.email) for user in users]) if __name__ == '__main__': app.run('127.0.0.1', 5000)

Hay algunas cosas a tener en cuenta aquí:

Primero, pierdes la capacidad de hacer User.query (porque el Usuario se creó utilizando su propia base declarativa), junto con todas las otras cosas que la db.Model de Flask-SQLAlchemy te da (como la capacidad de generar automáticamente la tabla Nombres y métodos como first_or_404() ).

Segundo, cada vez que necesite hacer cosas que involucren los metadatos (como drop_all o create_all ), no puede usar los métodos Flask-SQLAlchemy. Debe utilizar los metadatos originales, vinculados al motor Flask-SQLAlchemy.

No lo he intentado yo mismo, así que no estoy seguro de que haya algún otro problema con este enfoque. Es posible que desee participar en ese boleto si encuentra alguno.