在两个 Flask 应用程序之间共享 Flask-SQLAlchemy

问题描述 投票:0回答:1

我有两个使用域调度程序运行的 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 应用程序。)

python flask sqlalchemy flask-sqlalchemy
1个回答
0
投票

这不是完整的答案,请随意编辑或添加新答案。

既然您无论如何都在使用调度程序,请创建第三个应用程序来单独处理共享数据库和模型。 这样你的文件结构应该看起来像

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 自动排队请求,因此不需要会话处理。

© www.soinside.com 2019 - 2024. All rights reserved.