首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Flask-SQLAlchemy:既未设置SQLALCHEMY_DATABASE_URI也未设置SQLALCHEMY_BINDS。默认SQLALCHEMY_DATABASE_URI为“sqlite:/:memory:”

Flask-SQLAlchemy:既未设置SQLALCHEMY_DATABASE_URI也未设置SQLALCHEMY_BINDS。默认SQLALCHEMY_DATABASE_URI为“sqlite:/:memory:”
EN

Stack Overflow用户
提问于 2019-08-30 12:36:41
回答 2查看 17K关注 0票数 8

我第一次尝试同时使用flask应用程序工厂模式和pytest框架。我从sqlite db后端的基本健全性测试开始,虽然到目前为止测试运行良好,并且我看到测试db文件创建成功,但falsk_sqlalchemy告诉我它没有定义db后端。我试图找出pdb和交互式控制台的问题--一切看起来都很正常。看起来这似乎与谁能帮我弄明白问题出在哪里有关?

代码语言:javascript
运行
复制
(venv) C:\Users\dv\PycharmProjects\ste-speach-booking>python -m pytest tests/
=========================== test session starts ============================
platform win32 -- Python 3.6.8, pytest-5.1.1, py-1.8.0, pluggy-0.12.0
rootdir: C:\Users\dv\PycharmProjects\ste-speach-booking
collected 3 items

tests\test_models.py ...                                              [100%]

============================= warnings summary =============================
tests/test_models.py::test_init
  C:\Users\d837758\PycharmProjects\ste-speach-booking\venv\lib\site-packages\flask_sqlalchemy\__init__.py:814: UserWarning: Neither SQLALCHEMY_DATABASE_URI nor SQLALCHEMY_BINDS is set. Defaulting SQLALCHEMY_DATABASE_URI to "sqlite:///:memory:".
    'Neither SQLALCHEMY_DATABASE_URI nor SQLALCHEMY_BINDS is set. '

Test_models中的初始测试:

代码语言:javascript
运行
复制
import pytest
import src.models
import datetime

def test_ActionTypes(db):
    actiontype1 = src.models.Act_types(action_tyoe='workshop')
    db.session.add(actiontype1)
    db.session.commit()
    actiontype2 = src.models.Act_types(action_tyoe='speech')
    db.session.add(actiontype2)
    db.session.commit()
    count = db.session.query(src.models.Act_types).count()
    assert count is 2

def test_meeting_creation(db):
    meeting = src.models.Meeting(
        _date = datetime.datetime.strptime('2018-12-19', "%Y-%m-%d"),
    )
    db.session.add(meeting)
    db.session.commit()

db的conftest fixture:

代码语言:javascript
运行
复制
import os
import pytest
import src.config
from src import create_app
from src import db as _db

@pytest.fixture(scope='session')
def db():
    """Session-wide test database."""
    TESTDB_PATH = src.config.testDB
    print(TESTDB_PATH)
    if os.path.exists(TESTDB_PATH):
        os.unlink(TESTDB_PATH)
    app = create_app(config=src.config.TestingConfig)
    with app.app_context():
        _db.create_all()
        yield _db  
        _db.drop_all()
    os.unlink(TESTDB_PATH)

应用程序工厂:

代码语言:javascript
运行
复制
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()

def create_app(config=None):
    """Construct the core application."""
    app = Flask(__name__, instance_relative_config=True)
    db.init_app(app)
    if config is None:
        app.config.from_object(config.BaseConfig)
    else:
        app.config.from_object(config)

    with app.app_context():
        # Imports
        from . import routes
        db.create_all()

        return app

config.py:

代码语言:javascript
运行
复制
basedir = os.path.abspath(os.path.dirname(__file__))
baseDB = os.path.join(basedir, 'app.db')
devDB =  os.path.join(basedir, 'dev_app.db')
testDB = os.path.join(basedir, 'testing_app.db')

class BaseConfig(object):
    DEBUG = False
    TESTING = False
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess'
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
        'sqlite:///' + baseDB
    SQLALCHEMY_TRACK_MODIFICATIONS = False

class TestingConfig(BaseConfig):
    DEBUG = False
    TESTING = True
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
        'sqlite:///' + testDB
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-08-30 14:33:44

问题出在create_app()中应用程序组件的配置顺序上。

调用db.init_app(app)时,它执行的第一个操作是(source):

代码语言:javascript
运行
复制
        if (
            'SQLALCHEMY_DATABASE_URI' not in app.config and
            'SQLALCHEMY_BINDS' not in app.config
        ):
            warnings.warn(
                'Neither SQLALCHEMY_DATABASE_URI nor SQLALCHEMY_BINDS is set. '
                'Defaulting SQLALCHEMY_DATABASE_URI to "sqlite:///:memory:".'
            )

注意到这个警告了吗?

它会立即在app.config中查找所需的配置。该方法继续接受应用程序提供的配置或设置默认值,在本例中,默认值是内存中的数据库。

在您的create_app()实现中,对db.init_app()的调用是在配置应用程序本身之前进行的,其中包含以下内容:

代码语言:javascript
运行
复制
    db.init_app(app)
    if config is None:
        app.config.from_object(config.BaseConfig)
    else:
        app.config.from_object(config)

在填充app.config之前,应用程序上不存在任何带有SQLALCHEMY_前缀的配置,因此当db.init_app()查找它们时,它们不会被找到,并使用默认值。将db的配置移动到app的配置之后可以解决此问题:

代码语言:javascript
运行
复制
    if config is None:
        app.config.from_object(config.BaseConfig)
    else:
        app.config.from_object(config)
    db.init_app(app)

这与this question非常相似,但是我认为您的是典型设置( create_app()的范围和配置方法)的一个更好的例子,因此值得回答。

票数 20
EN

Stack Overflow用户

发布于 2021-09-25 19:42:42

确保app.config字典具有以下内容:

代码语言:javascript
运行
复制
app = Flask(__name__) # The URI config should be initialized after flask
['SQLALCHEMY_DATABASE_URI'] = 'to your database string'

然后:

代码语言:javascript
运行
复制
db = SQAlchemy(app)

也有同样的问题,因为我在数据库Uri连接之后进行了Flask初始化。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57720565

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档