SQLAlchemy的默认date时间
这是我的声明模型:
import datetime from sqlalchemy import Column, Integer 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'
如果我使用Integertypes,我可以设置一个默认值。 这是怎么回事?
DateTime
没有默认键作为input。 默认键应该是Column
函数的input。 尝试这个:
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)
计算您的数据库中的时间戳,而不是您的客户端
为了理智,您可能希望拥有由您的数据库服务器计算的所有datetimes
,而不是应用程序服务器。 计算应用程序中的时间戳可能会导致问题,因为networking延迟是可变的,客户端的时钟漂移略有不同,不同的编程语言偶尔计算时间稍有不同。
SQLAlchemy允许你通过传递func.now()
或func.current_timestamp()
(它们是彼此的别名func.current_timestamp()
来实现这一点,它告诉DB自己计算时间戳。
使用SQLALchemy的server_default
此外,对于已经告诉数据库来计算值的default
值,通常使用server_default
而不是default
。 这告诉SQLAlchemy将默认值作为CREATE TABLE
语句的一部分传递。
例如,如果您针对此表编写特别脚本,则使用server_default
意味着您不必担心手动将时间戳调用添加到脚本 – 数据库将自动设置它。
了解SQLAlchemy的onupdate
/ server_onupdate
SQLAlchemy也支持onupdate
以便在行更新的任何时候插入一个新的时间戳。 再次,最好告诉数据库来计算时间戳本身:
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,当更新发生时(也许你在列上创build了一个触发器 )你的数据库将会改变列,所以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文档中提供了func.utcnow()
的实现的一个存根。 但是,您需要自行提供适当的驱动程序特定function。
你也可以使用sqlalchemy内build函数来设定默认的DateTime
from sqlalchemy.sql import func DT = Column(DateTime(timezone=True), default=func.now())
应将该default
关键字参数提供给Column对象。
例:
Column(u'timestamp', TIMESTAMP(timezone=True), primary_key=False, nullable=False, default=time_now),
默认值可以是可调用的,在这里我定义如下。
from pytz import timezone from datetime import datetime UTC = timezone('UTC') def time_now(): return datetime.now(UTC)
[在此input链接描述] [1]
您可能想要使用onupdate = datetime.now,以便更新也更改last_updated字段。
[1]:SQLAlchemy有两个默认的python执行函数。
- 缺省值只在INSERT上设置一次
- onupdate也将该值设置为UPDATE上的可调用结果。