假设我有我的 Flask 应用程序的一部分,我想将其取出并用于多个不同的项目。它具有使用 Flask-SQLAlchemy 的 SQLAlchemy 模型,以及视图和模板。我可以通过使用模块来获取 app.route 装饰器,但是如何处理 SQLAlchemy db 对象?
由于我的组件需要分开,我不能只导入 db 对象。但我认为我不应该两次创建 db 对象。我如何将其元数据与项目其余部分的元数据混合在一起?
假设我有我的 Flask 应用程序的一部分,我想将其取出并用于多个不同的项目。它具有使用 Flask-SQLAlchemy 的 SQLAlchemy 模型,以及视图和模板。我可以通过使用模块来获取 app.route 装饰器,但是如何处理 SQLAlchemy db 对象?
由于我的组件需要分开,我不能只导入 db 对象。但我认为我不应该两次创建 db 对象。我如何将其元数据与项目其余部分的元数据混合在一起?
首先,您必须共享metadata
并且不要使用 flask-sqlalchemy db.Model 作为可重用应用程序的基础。
其次,您必须重新创建所有类,并从 flask-sqlalchemy 扩展它们的新基础,以支持信号、捷径和其他东西。
整合基地(可能有问题):
def integrate_models(cls, nbase):
new_bases = list(cls.__bases__) + [nbase]
new_dict = dict(cls.__dict__)
new_dict.update(dict(nbase.__dict__))
return type.__new__(cls.__class__, cls.__name__, tuple(new_bases), new_dict)
带有 sqlalchemy 扩展的示例 Flask 应用程序:
# -*- coding: utf-8 -*-
from flask import Flask
from flaskext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)
def __init__(self, username, email):
self.username = username
self.email = email
def __repr__(self):
return '<User %r>' % self.username
if __name__ == '__main__':
from some_model_base import init_metadata
init_metadata(db.Model.metadata)
from some_model import SomeClass
SomeClass = integrate_models(SomeClass, db.Model)
db.create_all()
print SomeClass.query.all()
其中 some_model_base.py:
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
def init_metadata(metadata):
Base.metadata = metadata
还有一些_model.py:
from sqlalchemy import Column, Integer, String
from some_model_base import Base
class SomeClass(Base):
__tablename__ = 'some_table'
id = Column(Integer, primary_key=True)
name = Column(String(50))
在这个例子中只测试了 db.create_all 和 SomeClass.query 快捷方式。
对不起我的英语不好。
您应该使用flask.current_app
,它是访问当前应用程序的代理对象,它是在某些扩展中使用的。因此,您的代码将如下所示:
from flask import current_app
from flaskext.sqlalchemy import SQLAlchemy
db = SQLAlchemy(current_app)
然后db
像往常一样使用你的对象。但是我不确定如果用户使用了您的模块并且还需要使用这是否可行flaskext.sqlalchemy
,也许它会发生冲突,我建议对此进行测试,以确保您的模块与任何flask
应用程序 100% 兼容。