Sco*_*son 5 python flask flask-sqlalchemy
我正在为我的 Flask 应用程序编写一个使用 Flask-SQLAlchemy 的测试。在 中models.py,我使用了db = SQLAlchemy(),并编写了一个函数来使用应用程序对其进行配置。但是当我运行测试时,我收到错误“RuntimeError:“SQLAlchemy”实例已在此 Flask 应用程序上注册”。我不确定测试文件在哪里创建 SQLAlchemy 的新实例。
# flaskr.py
from flask import Flask
from models import setup_db
def create_app(test_config=None):
app = Flask(__name__)
setup_db(app)
return app
Run Code Online (Sandbox Code Playgroud)
# models.py
from flask_sqlalchemy import SQLAlchemy
database_path = "postgresql://student:student@localhost/bookshelf"
db = SQLAlchemy()
def setup_db(app, database_path=database_path):
app.config["SQLALCHEMY_DATABASE_URI"] = database_path
db.init_app(app)
with app.app_context():
db.create_all()
Run Code Online (Sandbox Code Playgroud)
# test_flaskr.py
import unittest
from flaskr import create_app
from models import setup_db
class BookTestCase(unittest.TestCase):
def setUp(self):
self.app = create_app()
self.client = self.app.test_client()
setup_db(self.app, "postgresql://student:student@localhost/bookshelf_test")
with self.app.app_context():
self.db = SQLAlchemy()
self.db.init_app(self.app)
self.db.create_all()
def test_get_paginated_books(self):
res = self.client.get("/books")
data = res.json
self.assertEqual(res.status_code, 200)
self.assertTrue(data["success"])
self.assertTrue(data["total_books"])
self.assertTrue(len(data["books"]))
Run Code Online (Sandbox Code Playgroud)
当我运行测试时,出现以下错误:
# test_flaskr.py
import unittest
from flaskr import create_app
from models import setup_db
class BookTestCase(unittest.TestCase):
def setUp(self):
self.app = create_app()
self.client = self.app.test_client()
setup_db(self.app, "postgresql://student:student@localhost/bookshelf_test")
with self.app.app_context():
self.db = SQLAlchemy()
self.db.init_app(self.app)
self.db.create_all()
def test_get_paginated_books(self):
res = self.client.get("/books")
data = res.json
self.assertEqual(res.status_code, 200)
self.assertTrue(data["success"])
self.assertTrue(data["total_books"])
self.assertTrue(len(data["books"]))
Run Code Online (Sandbox Code Playgroud)
Flask-SQLAlchemy 3 会因扩展的常见错误设置而引发错误。db.init_app(app)对于给定的db和实例对,您只能调用一次app。
您db = SQLAlchemy()在 中定义models,然后init_app在 中调用它create_app。您必须使用它db,而不是创建另一个实例。你不能db.init_app再打电话了,已经被叫进来了create_app。
您的测试setUp正在调用create_app,但随后它也会setup_db再次调用,即使它已经作为 的一部分被调用create_app。然后,再往下,您将创建一个新实例self.db = SQLAlchemy(),并init_app使用您已经设置了另一个实例的同一应用程序来调用它。这都是不正确的。
您这样做似乎是因为您正在尝试为测试设置数据库配置。正如Flask 教程中所解释的,这就是create_app函数参数的test_config用途。去掉这个setup_db函数,这是不必要的间接。将您的测试配置传递给工厂以覆盖默认配置。
def create_app(test_config=None):
app = Flask(__name__)
app.config.from_mapping(
SQLALCHEMY_DATABASE_URI="postgresql://student:student@localhost/bookshelf"
)
if test_config is not None:
app.config.from_mapping(test_config)
db.init_app(app)
with app.app_context():
db.create_all()
return app
Run Code Online (Sandbox Code Playgroud)
from flaskr import create_app, db
class BookTestCase(TestCase):
def setUp(self):
self.app = create_app({
"SQLALCHEMY_DATABASE_URI": "postgresql://student:student@localhost/bookshelf_test"
})
Run Code Online (Sandbox Code Playgroud)
db请注意, in没有直接执行任何操作setUp,它只是导入以在测试期间使用。