在 Flask 应用程序中使用测试 peewee 数据库实例
Using a test peewee database instance in a Flask app
我想 运行 我的网站(目前 运行ning 使用 Flask 服务器)和测试数据。我正在使用我从测试中初始化的 peewee 数据库代理。我的模型是:
database_proxy = Proxy()
class MySQLModel(Model):
""" A base model that will use our MySQL database """
class Meta:
database = database_proxy
class Person(MySQLModel):
id = PrimaryKeyField(primary_key=True)
name = CharField()
在测试过程中,我创建了一个新的内存数据库:
test_db = SqliteDatabase(':memory:')
并初始化模型的数据库:
database_proxy.initialize(test_db)
if database_proxy.is_closed():
database_proxy.connect()
Person.create_table()
然后我创建数据,运行 我的 Flask 服务器:
app = Flask(__name__)
app.run(debug=True)
我的一条路线选择了我数据库中的所有人员。但这会引发异常,表示 table 人不存在。对于好奇的人,函数是:
@app.route("/api/people")
def list_people():
ppl = models.Person.select(models.Person.id).dicts().execute()
[ ... formatting and returning a json ... ]
如果我 运行 在服务器外部进行相同的查询,当然可以。
我确保我的 Flask 应用程序使用相同的数据库实例,通过调试并看到模型 Person 在我的测试和 flask 函数中使用相同的 SqliteDatabase 对象(我检查了内存地址是相同的)。
这是怎么回事?当我在 flask 中查询时,我的数据在哪里?
示例调试 运行:
[在运行宁app.run()之前]
>>> models.Person.get()
<database.models.Person object at 0x7f8dde8e09d0>
>>> models.Person._meta.database.obj
<peewee.SqliteDatabase object at 0x7f8dde8e0190>
[在 app.run()]
之后
* Debugger is active!
* Debugger pin code: 327-505-347
127.0.0.1 - - [03/May/2016 16:36:12] "GET / HTTP/1.1" 200 -
... Loads more pages ...
>>> models.Person._meta.database.obj
<peewee.SqliteDatabase object at 0x7f8dde8e0190>
>>> models.Person.get()
Traceback (most recent call last):
File "/home/q/Software/pycharm-2016.1.2/helpers/pydev/_pydevd_bundle/pydevd_exec.py", line 3, in Exec
exec exp in global_vars, local_vars
File "<input>", line 1, in <module>
File "/home/q/dev/dev/venv/local/lib/python2.7/site-packages/peewee.py", line 4505, in get
return sq.get()
File "/home/q/dev/dev/venv/local/lib/python2.7/site-packages/peewee.py", line 2885, in get
return next(clone.execute())
File "/home/q/dev/dev/venv/local/lib/python2.7/site-packages/peewee.py", line 2932, in execute
self._qr = ResultWrapper(model_class, self._execute(), query_meta)
File "/home/q/dev/dev/venv/local/lib/python2.7/site-packages/peewee.py", line 2628, in _execute
return self.database.execute_sql(sql, params, self.require_commit)
File "/home/q/dev/dev/venv/local/lib/python2.7/site-packages/peewee.py", line 3461, in execute_sql
self.commit()
File "/home/q/dev/dev/venv/local/lib/python2.7/site-packages/peewee.py", line 3285, in __exit__
reraise(new_type, new_type(*exc_args), traceback)
File "/home/q/dev/dev/venv/local/lib/python2.7/site-packages/peewee.py", line 3454, in execute_sql
cursor.execute(sql, params or ())
OperationalError: no such table: person
我没有深入研究 peewee 的实现,但我的猜测是这个问题是由 peewee 中的某些线程管理机制引起的,至少对于 Sqlite 内存 DB 是这样。也许它将内容保存在 TLS 中。
使用文件数据库代替内存数据库解决了这个问题。
从未使用过 Flask,但该应用程序是否可以在启动时初始化不同的数据库?我看不出你在哪里告诉 Flask 有关新数据库的信息,这让我感到奇怪。
您能否改为创建数据库条目作为 Flask 初始化的一部分(在您调用 app = Flask(__name__)
之后?查看 this peewee example。
我想 运行 我的网站(目前 运行ning 使用 Flask 服务器)和测试数据。我正在使用我从测试中初始化的 peewee 数据库代理。我的模型是:
database_proxy = Proxy()
class MySQLModel(Model):
""" A base model that will use our MySQL database """
class Meta:
database = database_proxy
class Person(MySQLModel):
id = PrimaryKeyField(primary_key=True)
name = CharField()
在测试过程中,我创建了一个新的内存数据库:
test_db = SqliteDatabase(':memory:')
并初始化模型的数据库:
database_proxy.initialize(test_db)
if database_proxy.is_closed():
database_proxy.connect()
Person.create_table()
然后我创建数据,运行 我的 Flask 服务器:
app = Flask(__name__)
app.run(debug=True)
我的一条路线选择了我数据库中的所有人员。但这会引发异常,表示 table 人不存在。对于好奇的人,函数是:
@app.route("/api/people")
def list_people():
ppl = models.Person.select(models.Person.id).dicts().execute()
[ ... formatting and returning a json ... ]
如果我 运行 在服务器外部进行相同的查询,当然可以。
我确保我的 Flask 应用程序使用相同的数据库实例,通过调试并看到模型 Person 在我的测试和 flask 函数中使用相同的 SqliteDatabase 对象(我检查了内存地址是相同的)。
这是怎么回事?当我在 flask 中查询时,我的数据在哪里?
示例调试 运行:
[在运行宁app.run()之前]
>>> models.Person.get()
<database.models.Person object at 0x7f8dde8e09d0>
>>> models.Person._meta.database.obj
<peewee.SqliteDatabase object at 0x7f8dde8e0190>
[在 app.run()]
之后* Debugger is active!
* Debugger pin code: 327-505-347
127.0.0.1 - - [03/May/2016 16:36:12] "GET / HTTP/1.1" 200 -
... Loads more pages ...
>>> models.Person._meta.database.obj
<peewee.SqliteDatabase object at 0x7f8dde8e0190>
>>> models.Person.get()
Traceback (most recent call last):
File "/home/q/Software/pycharm-2016.1.2/helpers/pydev/_pydevd_bundle/pydevd_exec.py", line 3, in Exec
exec exp in global_vars, local_vars
File "<input>", line 1, in <module>
File "/home/q/dev/dev/venv/local/lib/python2.7/site-packages/peewee.py", line 4505, in get
return sq.get()
File "/home/q/dev/dev/venv/local/lib/python2.7/site-packages/peewee.py", line 2885, in get
return next(clone.execute())
File "/home/q/dev/dev/venv/local/lib/python2.7/site-packages/peewee.py", line 2932, in execute
self._qr = ResultWrapper(model_class, self._execute(), query_meta)
File "/home/q/dev/dev/venv/local/lib/python2.7/site-packages/peewee.py", line 2628, in _execute
return self.database.execute_sql(sql, params, self.require_commit)
File "/home/q/dev/dev/venv/local/lib/python2.7/site-packages/peewee.py", line 3461, in execute_sql
self.commit()
File "/home/q/dev/dev/venv/local/lib/python2.7/site-packages/peewee.py", line 3285, in __exit__
reraise(new_type, new_type(*exc_args), traceback)
File "/home/q/dev/dev/venv/local/lib/python2.7/site-packages/peewee.py", line 3454, in execute_sql
cursor.execute(sql, params or ())
OperationalError: no such table: person
我没有深入研究 peewee 的实现,但我的猜测是这个问题是由 peewee 中的某些线程管理机制引起的,至少对于 Sqlite 内存 DB 是这样。也许它将内容保存在 TLS 中。
使用文件数据库代替内存数据库解决了这个问题。
从未使用过 Flask,但该应用程序是否可以在启动时初始化不同的数据库?我看不出你在哪里告诉 Flask 有关新数据库的信息,这让我感到奇怪。
您能否改为创建数据库条目作为 Flask 初始化的一部分(在您调用 app = Flask(__name__)
之后?查看 this peewee example。