我有两个使用域调度程序运行的 Flask 应用程序(基于 本指南)。
我想在应用程序之间共享我的模型。将
SQLAlchemy
对象放在共享位置并仅使用两个应用程序调用 db.init_app
是否安全?
这是我的项目结构:
app_one/
├ __init__.py
├ database/
│ ├ __init__.py
│ └ models.py
└ ...
app_two/
├ __init__.py
├ database/
│ ├ __init__.py
│ └ models.py
└ ...
shared/
└ ...
dispatcher.py
这是
dispatcher.py
:
from flask import Flask
import app_one
import app_two
class Dispatcher:
def __init__(self, config_file, app_one_config_file, app_two_config_file):
self.app_one = app_one.create_app(config_file, app_one_config_file)
self.app_two = app_two.create_app(config_file, app_two_config_file)
def __call__(self, environ, start_response):
host = environ['HTTP_HOST']
if host == 'app_two_domain.com':
return self.app_two(environ, start_response)
return self.app_one(environ, start_response)
def create_app(*args, **kwargs):
app = Flask(__name__)
app.wsgi_app = Dispatcher(*args, **kwargs)
return app
目前
app_one/database/__init__.py
和app_two/database/__init__.py
都包含:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy
在两个
create_app
功能中:
from .database import db
db.init_app(app)
我想将
db
移至 shared/database/__init__.py
,然后:
使用两个应用程序拨打
init_app
,或者
使
Dispatcher
成为 Flask
的子类,在 init_app
中调用 Dispatcher
,然后使用 app.extensions['sqlalchemy'] = _SQLAlchemyState(db)
向两个应用程序注册 Flask-SQLAlchemy 扩展。
解决这个问题的正确方法是什么? (拆分
app_one
和 app_two
不是一个选项。)
(注意:这不是这个问题的重复,因为我的两个应用程序都是 Flask 应用程序。)
这不是完整的答案,请随意编辑或添加新答案。
既然您无论如何都在使用调度程序,请创建第三个应用程序来单独处理共享数据库和模型。 这样你的文件结构应该看起来像
shared_db_app/
├ __init__.py
└ database/
├ __init__.py
└ models.py
app_one/
├ __init__.py
├ database/
│ ├ __init__.py
│ └ models.py
└ ...
app_two/
├ __init__.py
├ database/
│ ├ __init__.py
│ └ models.py
└ ...
dispatcher.py
初始化部分
您的共享应用程序
shared/database/__init__.py
应类似于:
from flask import Flask
from sqlalchemy import SQLAlchemy
from sqlalchemy.orm import scoped_session, sessionmaker
db = SQLAlchemy()
def init_db(app):
db.init_app(app)
@app.teardown_appcontext
def remove_session(*args, **kwargs):
db.session.remove()
app.db_session = scoped_session(sessionmaker(autocommit=False,autoflush=False,bind=db.engine))
def get_session():
return Flask(__name__).db_session
每个应用程序都将其称为:
from flask import Flask
from shared.database import init_db, get_session
app #whatever init you have to do
init_db(app)
app.db_session = get_session()
模型部分
现在您的模型应该全部位于共享
shared_db_app/database/models.py
中,如下所示:
from shared_db_app.database import db
class User(db.Model):#eg
应用程序 1 和 2 中的模型导入它(假设您也有单独的数据或模型要在每个应用程序中处理):
from shared_db_app.database.models import User
这两个链接可能令人感兴趣(不幸的是,两者都不包含代码或任何更多详细信息):
在这种情况下处理迁移
回答同一主题,这表示由于 sql 自动排队请求,因此不需要会话处理。