programing tip

SQLAlchemy 기본 DateTime

itbloger 2020. 6. 30. 20:55
반응형

SQLAlchemy 기본 DateTime


이것은 나의 선언적 모델입니다.

import datetime
from sqlalchemy import Column, Integer, DateTime
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Test(Base):
    __tablename__ = 'test'

    id = Column(Integer, primary_key=True)
    created_date = DateTime(default=datetime.datetime.utcnow)

그러나이 모듈을 가져 오려고하면 다음 오류가 발생합니다.

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "orm/models2.py", line 37, in <module>
    class Test(Base):
  File "orm/models2.py", line 41, in Test
    created_date = sqlalchemy.DateTime(default=datetime.datetime.utcnow)
TypeError: __init__() got an unexpected keyword argument 'default'

정수 유형을 사용하면 기본값을 설정할 수 있습니다. 무슨 일이야?


DateTime기본 키가 입력으로 없습니다. 기본 키는 Column기능에 대한 입력이어야합니다 . 이 시도:

import datetime
from sqlalchemy import Column, Integer, DateTime
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Test(Base):
    __tablename__ = 'test'

    id = Column(Integer, primary_key=True)
    created_date = Column(DateTime, default=datetime.datetime.utcnow)

클라이언트가 아닌 DB 내 타임 스탬프 계산

건강을 위해 아마도 datetimes응용 프로그램 서버가 아닌 DB 서버에서 모두 계산 해야 할 것입니다 . 응용 프로그램에서 타임 스탬프를 계산하면 네트워크 대기 시간이 가변적이고 클라이언트가 약간 다른 클럭 드리프트를 경험하며 프로그래밍 언어에 따라 시간이 약간 다르게 계산되므로 문제가 발생할 수 있습니다.

SQLAlchemy를 사용하면 DB에 타임 스탬프 자체를 계산하도록 지시 하는 func.now()또는 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는 반환 값을 요청하여 해당 개체를 업데이트 할 수 있습니다.

또 다른 잠재력은 다음과 같습니다.

단일 트랜잭션 내에서 많은 변경을 수행하면 모두 동일한 타임 스탬프를가집니다. SQL 표준 CURRENT_TIMESTAMP은 트랜잭션 시작에 따라 값 반환하도록 지정하기 때문 입니다.

PostgreSQL provides the non-SQL-standard statement_timestamp() and clock_timestamp() which do change within a transaction. Docs here: https://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT

UTC timestamp

If you want to use UTC timestamps, a stub of implementation for func.utcnow() is provided in SQLAlchemy documentation. You need to provide appropriate driver-specific functions on your own though.


You can also use sqlalchemy builtin function for default DateTime

from sqlalchemy.sql import func

DT = Column(DateTime(timezone=True), default=func.now())

The default keyword parameter should be given to the Column object.

Example:

Column(u'timestamp', TIMESTAMP(timezone=True), primary_key=False, nullable=False, default=time_now),

The default value can be a callable, which here I defined like the following.

from pytz import timezone
from datetime import datetime

UTC = timezone('UTC')

def time_now():
    return datetime.now(UTC)

You likely want to use onupdate=datetime.now so that UPDATEs also change the last_updated field.

SQLAlchemy has two defaults for python executed functions.

  • default sets the value on INSERT, only once
  • onupdate sets the value to the callable result on UPDATE as well.

As per PostgreSQL documentation, https://www.postgresql.org/docs/9.6/static/functions-datetime.html

now, CURRENT_TIMESTAMP, LOCALTIMESTAMP return the time of transaction.

This is considered a feature: the intent is to allow a single transaction to have a consistent notion of the "current" time, so that multiple modifications within the same transaction bear the same time stamp.

You might want to use statement_timestamp or clock_timestamp if you don't want transaction timestamp.

statement_timestamp()

returns the start time of the current statement (more specifically, the time of receipt of the latest command message from the client). statement_timestamp

clock_timestamp()

returns the actual current time, and therefore its value changes even within a single SQL command.

참고URL : https://stackoverflow.com/questions/13370317/sqlalchemy-default-datetime

반응형