gpt4 book ai didi

python - 如何使用 flask、SQLAlchemy 和 declarative_base 避免硬编码数据库路径

转载 作者:太空宇宙 更新时间:2023-11-04 04:39:22 25 4
gpt4 key购买 nike

Flask-SQLAlchemy 建议 Declarative用于建立数据库连接的模式。该示例对单个数据库路径进行了硬编码,看来我应该避免这种情况,以便我可以为单元测试、本地开发和最终生产配置不同的数据库。

这是他们的database.py:

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()

def init_db():
# import all modules here that might define models so that
# they will be registered properly on the metadata. Otherwise
# you will have to import them first before calling init_db()
import yourapplication.models
Base.metadata.create_all(bind=engine)

但我一直无法弄清楚如何避免硬编码此数据库路径。

环境变量:

我可以用环境变量替换 sqlite:///.... 路径。但这需要一些方法让 pytest 使用一组环境变量运行,而 flask run 使用另一组。我宁愿让我的单元测试跟踪它们自己的临时数据库。 [2]我还喜欢 create_app() 创建 Flask 应用程序以采用作为配置变量的数据库路径。

在应用程序上下文中导入 database.py

我想我可以用 current_app.config['DB'] 替换数据库路径,并在 with app.app_context() 中导入数据库。但是模型类需要导入 Base,我不能在应用程序上下文中对 Base 进行子类化。因此,当加载模型时,它们是在应用程序上下文之外加载的,这会引发运行时错误。

那么在带单元测试的 Flask 应用程序中使用 declarative_base 的正确方法是什么?

感谢您的帮助!

[2]:如果那是我应该做的,那么我可以接受。但是,当我也使用自己的配置变量配置 Flask 应用程序时,在那里使用环境变量似乎很麻烦。

最佳答案

我已经解决了我的问题。而不是使用 declarative_base 类工厂:

数据库.py:

engine="someengine"
db_session=[make a session here]
Base = declarative_base()
Base.query = db_session.query

让我的模型导入 Base,

我只是遵循了 here 的模式.在 database.py 中,我用

创建了一个哑数据库
db = SQLAlchemy()

然后在 init.py 中,在 create_app 应用工厂中,我可以使用应用配置变量初始化应用并使用应用初始化数据库。*

db.init_app(app)
with app.app_context():
import site.models
db.create_all()

模型继承自 database.py 的 db.Model 类。

from site.database import db
class MyModel(db.Model)

我可以通过将测试包装在夹具中来访问 pytest 测试中的数据库:

@pytest.fixture
def app():
app = create_app({[testing config]}
with app.app_context():
g.db = db
yield app
g.db.session.remove()
g.db.drop_all()

现在这对我有用。也就是说,如果您认为我做错了什么,请告诉我!

*我认为 SQLAlchemy 对象一旦用 init_app 初始化,就会存储指向仅在存在事件应用程序上下文时才存在的值的指针?是对的吗?这就是为什么仅调用 db 不会连接到应用程序数据库,但在应用程序上下文中调用 db 却可以。

关于python - 如何使用 flask、SQLAlchemy 和 declarative_base 避免硬编码数据库路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51010285/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com