Django:获取CURRENT_TIMESTAMP的原始sql查询未在后续调用中更新

时间:2012-11-01 17:42:36

标签: django postgresql

我有以下代码片段用于从db服务器获取当前时间戳:

class DbUtils:
    @staticmethod
    def get_current_timestamp():
        from django.db import connection
        cursor = connection.cursor()
        cursor.execute("SELECT CURRENT_TIMESTAMP")
        rows = cursor.fetchone()
        return rows[0]

为了测试这段代码,我编写了以下测试:

def test_get_current_timestamp(self):
    ts_0 = DbUtils.get_current_timestamp()
    time.sleep(1)
    ts_1 = DbUtils.get_current_timestamp()
    delta_seconds = (ts_1 - ts_0).seconds
    assert 1 <= delta_seconds <= 3

这个测试没有通过,所以我稍微挖了一下。原因是每次对DbUtils.get_current_timestamp()的调用每次都返回相同的值。

In [31]: DbUtils.get_current_timestamp()
Out[31]: datetime.datetime(2012, 11, 1, 17, 17, 48, 950799, tzinfo=<UTC>)

# Wait a couple seconds

In [32]: DbUtils.get_current_timestamp()
Out[32]: datetime.datetime(2012, 11, 1, 17, 17, 48, 950799, tzinfo=<UTC>)

我监控了postgresql日志 - 每个查询都在点击db。

我能够完成这项工作的唯一方法是在执行SELECT之前导入django.db.transaction并执行transaction.commit_unless_managed()。在SELECT之前提交事务似乎不正确,因为我不知道将在什么上下文中调用get_current_timestamp。关于如何解决这个问题或解决它的任何想法?时间戳需要来自数据库服务器,以确保正确完成所有相对时间计算。

我正在跑步:

Django==1.4.2
psycopg2==2.4.5 (with hstore extension via django-hstore==1.1.1)
PostgreSQL 9.1

1 个答案:

答案 0 :(得分:3)

在与同事讨论后,我们意识到这实际上可能是理想的行为,因为我们每个网页请求只会得到一个时间戳。在任何情况下,我通常都会存储get_current_timestamp的返回值,并将其用于该请求期间的任何操作。

要进行测试,我需要执行以下操作:

def test_get_current_timestamp(self):
    from django.db import transaction
    ts_0 = DbUtils.get_current_timestamp()
    transaction.commit_unless_managed()
    time.sleep(1)
    ts_1 = DbUtils.get_current_timestamp()
    transaction.commit_unless_managed()
    delta_seconds = (ts_1 - ts_0).seconds
    assert 1 <= delta_seconds <= 3

作为@a_horse_with_no_name注意:CURRENT_TIMESTAMP是交易开始时的时间。