[python] 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은 비 SQL 표준 제공 statement_timestamp()하고 clock_timestamp()있는 트랜잭션 내에서 변화를. 여기 문서 : https://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT

UTC 타임 스탬프

UTC 타임 스탬프를 사용하려면 SQLAlchemy documentation 에 구현 스텁 func.utcnow()이 제공됩니다 . 그래도 적절한 드라이버 별 기능을 제공해야합니다.


답변

sqlalchemy 내장 함수를 기본값으로 사용할 수도 있습니다 DateTime

from sqlalchemy.sql import func

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


답변

onupdate=datetime.nowUPDATE가 last_updated필드를 변경 하도록 사용하고 싶을 수도 있습니다 .

SQLAlchemy에는 파이썬 실행 함수에 대한 두 가지 기본값이 있습니다.

  • default INSERT에 값을 한 번만 설정합니다.
  • onupdateUPDATE시에도 호출 가능한 결과로 값을 설정합니다 .

답변

그만큼 default키워드 매개 변수는 열 개체에 부여해야합니다.

예:

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

기본값은 callable 일 수 있으며 여기서는 다음과 같이 정의했습니다.

from pytz import timezone
from datetime import datetime

UTC = timezone('UTC')

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


답변

PostgreSQL 설명서에 따라 https://www.postgresql.org/docs/9.6/static/functions-datetime.html

now, CURRENT_TIMESTAMP, LOCALTIMESTAMP return the time of transaction.

이는 하나의 기능으로 간주됩니다. 의도는 단일 트랜잭션이 “현재”시간에 대해 일관된 개념을 갖도록하여 동일한 트랜잭션 내에서 여러 수정이 동일한 타임 스탬프를 갖도록하는 것입니다.

statement_timestamp 또는 clock_timestamp 를 사용할 수 있습니다트랜잭션 타임 스탬프를 원하지 않으면 .

statement_timestamp ()

현재 문의 시작 시간 (특히 클라이언트로부터 최신 명령 메시지를받은 시간)을 반환합니다. statement_timestamp

clock_timestamp ()

실제 현재 시간을 리턴하므로 단일 SQL 명령 내에서도 값이 변경됩니다.


답변