クライアントではなく、DB内でタイムスタンプを計算する
正気のために、おそらくすべてを持っている datetimes
アプリケーションサーバーではなくDBサーバーで計算する必要があります。アプリケーションでタイムスタンプを計算すると、ネットワーク遅延が変動し、クライアントでわずかに異なるクロックドリフトが発生し、異なるプログラミング言語では時間の計算がわずかに異なるため、問題が発生する可能性があります。
SQLAlchemyを使用すると、タイムスタンプ自体を計算するようにDBに指示するfunc.now()
or func.current_timestamp()
(これらはお互いのエイリアスです)を渡すことでこれを行うことができます。
SQLALchemyの server_default
さらに、デフォルトで値を計算するようにDBに指示している場合は、通常、server_default
ではなくを使用することをお勧めしますdefault
。これは、SQLAlchemyにデフォルト値をCREATE TABLE
ステートメントの一部として渡すように指示します。
たとえば、このテーブルに対してアドホックスクリプトを作成する場合は、 server_default
すると、スクリプトにタイムスタンプコールを手動で追加することを心配する必要がなくなります。データベースによって自動的に設定されます。
SQLAlchemyのonupdate
/を理解するserver_onupdate
SQLAlchemy onupdate
は、行が更新されるたびに新しいタイムスタンプを挿入することもサポートしています。繰り返しになりますが、タイムスタンプ自体を計算するようにDBに指示するのが最善です。
from sqlalchemy.sql import func
time_created = Column(DateTime(timezone=True), server_default=func.now())
time_updated = Column(DateTime(timezone=True), onupdate=func.now())
server_onupdate
パラメータはありますがserver_default
、とは異なり、サーバーサイドでは実際には何も設定しません。これは、更新が発生したときにデータベースが列を変更することをSQLalchemyに通知するだけで(おそらく列にトリガーを作成したため)、SQLAlchemyは戻り値を要求し、対応するオブジェクトを更新できるようにします。
もう1つの潜在的な問題:
単一のトランザクション内で一連の変更を行った場合、それらはすべて同じタイムスタンプを持つことに驚くかもしれません。これは、SQL標準で次のように指定されているためです。CURRENT_TIMESTAMP
トランザクションの開始に基づいて値を返すようにです。
PostgreSQLは非SQL標準statement_timestamp()
を提供し、トランザクション内で変更clock_timestamp()
を行います。ここにドキュメント:https : //www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT
UTCタイムスタンプ
UTCタイムスタンプを使用する場合、の実装のスタブがSQLAlchemyドキュメントにfunc.utcnow()
提供されています。ただし、適切なドライバ固有の機能を自分で提供する必要があります。