gpt4 book ai didi

python - 如何在 sqlalchemy 中模拟创建时间?

转载 作者:太空狗 更新时间:2023-10-30 00:10:35 25 4
gpt4 key购买 nike

我在 Flask 应用程序中使用 SQLAlchemy。在我的测试中,我尝试为我的条目模拟自动时间创建和更新。但我不明白它是如何为 SQLAlchemy 工作的。例如,我尝试模拟使用 freezgun 创建的日期时间,却是失败。例如:

class Entry(db.Model):
__tablename__ = 'entries'
created = db.Column(db.DateTime(), default=db.func.now())
updated = db.Column(db.DateTime(), default=db.func.now(), onupdate=db.func.now())

class ViewTestCase(AppliactionTestCase):
def test(self):
with freeze_time("2014-06-01 16:00:00"):
db.session.add(Entry())
db.session.commit()
entry = db.session.query(Entry).first()
self.assertEqual(entry.created, datetime(2014, 6, 1, 16, 0, 0))

还有一个问题。如果我需要刷新 updated 以进行输入,如何在没有更改的情况下强制保存输入?

最佳答案

sqlalchemy 提供 Hook sqlalchemy.event api 来修补查询 session 。

先决条件:flask-sqlalchemy、pytest、freezengun、contextlib

以@prokoptesev 使用的 flask-sqlalchemy 为例:

class Entry(db.Model):
__tablename__ = 'entries'
created = db.Column(db.DateTime(), default=db.func.now())
updated = db.Column(db.DateTime(), default=db.func.now(), onupdate=db.func.now())

只需编写一个 pytest fixtures 来修补行创建时间:

import datetime
from flask_sqlalchemy import event
from contextlib import contextmanager
from freezegun import freeze_time

import Entry
# if you want the code be commonly used, change Entry to db.Model instead


@contextmanager
def patch_time(time_to_freeze, tick=True):
with freeze_time(time_to_freeze, tick=tick) as frozen_time:
def set_timestamp(mapper, connection, target):
now = datetime.datetime.now()
if hasattr(target, 'created'):
target.created = now
if hasattr(target, 'updated'):
target.updated = now
event.listen(Entry, 'before_insert', set_timestamp,
propagate=True)
yield frozen_time
event.remove(Entry, 'before_insert', set_timestamp)


@pytest.fixture(scope='function')
def patch_current_time():
return patch_time

然后写一个pytest类型的测试用例:

def test_patch_insert_time(patch_current_time, assertions):
with patch_current_time("2014-06-01 16:00:00", tick=False):
db.session.add(Entry())
db.session.commit()
entry = db.session.query(Entry).first()
assert entry.created == datetime(2014, 6, 1, 16, 0, 0)

如果有人使用unittools或者其他测试包,你也可以直接使用patch_time函数:

class ViewTestCase(AppliactionTestCase):
def test(self):
with patch_time("2014-06-01 16:00:00", tick=False):
db.session.add(Entry())
db.session.commit()
entry = db.session.query(Entry).first()
self.assertEqual(entry.created, datetime(2014, 6, 1, 16, 0, 0))

快乐编码。

关于python - 如何在 sqlalchemy 中模拟创建时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29116718/

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