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ログを監視しました-各クエリはデータベースにヒットしていました。
この作業を行うことができた唯一の方法は、django.db.transactionをインポートしtransaction.commit_unless_managed()
て、SELECTを実行する前に実行することでした。get_current_timestampがどのコンテキストで呼び出されるかわからないため、SELECTの前にトランザクションをコミットすることは正しくないようです。これを修正する方法や回避する方法について何かアイデアはありますか?すべての相対時間の計算が正しく行われるようにするには、タイムスタンプをdbサーバーから取得する必要があります。
私は走っています:
Django==1.4.2
psycopg2==2.4.5 (with hstore extension via django-hstore==1.1.1)
PostgreSQL 9.1