이것은 나의 선언적 모델입니다.
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.now
UPDATE가 last_updated
필드를 변경 하도록 사용하고 싶을 수도 있습니다 .
SQLAlchemy에는 파이썬 실행 함수에 대한 두 가지 기본값이 있습니다.
default
INSERT에 값을 한 번만 설정합니다.onupdate
UPDATE시에도 호출 가능한 결과로 값을 설정합니다 .
답변
그만큼 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 명령 내에서도 값이 변경됩니다.