9

我有一个 sqlalchemy 类映射到 MySQL innoDB 中的数据库表。该表有几列,除了 TIMESTAMP 列之外,我能够成功填充它们:

映射:

class HarvestSources(Base):
    __table__ = Table('harvested', metadata, autoload=True)

MySQL 上的列是一个 TIMESTAMP,它具有 CURRENT_TIMESTAMP 作为默认值,但是当我插入一行时,它被填充为 NULL。

如果默认值不起作用,那么我需要手动设置时间戳,我该怎么做。

将行插入表的 SqlAlchemy 代码:

source = HarvestSources()
source.url = url
source.raw_data = data
source.date = ?

DB.session.add(source)
DB.session.commit()
4

2 回答 2

16

datetime对象被转换为时间戳,所以你可以使用:

from datetime import datetime
...
source.date = datetime.now()

或者datetime.utcnow()如果您想使用 utc 保存它。默认 ( CURRENT_TIMESTAMP) 使用本地时区,因此datetime.now()更接近于本地时区 - 但几乎总是应该以 UTC 存储与时间相关的数据,并且仅在向用户呈现数据时进行时区转换。

于 2013-07-23T20:21:08.727 回答
16

mata answer is very clear on how to add a timestamp value. If you want to add the timestamp added automatically on insert and update. You may consider have a BaseMixin class and register sqlalchemy event for every class. Example implementation is below:

class BaseMixin(object):

  __table_args__ = {'mysql_engine': 'InnoDB'}

  id = sa.Column(sa.Integer, primary_key=True)
  created_at = sa.Column('created_at', sa.DateTime, nullable=False)
  updated_at = sa.Column('updated_at', sa.DateTime, nullable=False)

  @staticmethod
  def create_time(mapper, connection, instance):
     now = datetime.datetime.utcnow()
     instance.created_at = now
     instance.updated_at = now

  @staticmethod
  def update_time(mapper, connection, instance):
     now = datetime.datetime.utcnow()
     instance.updated_at = now

  @classmethod
  def register(cls):
     sa.event.listen(cls, 'before_insert', cls.create_time)
     sa.event.listen(cls, 'before_update', cls.update_time)

change your class HarvestSources(Base): to class HarvestSources(Base, BaseMixin):. call HarvestSources.register() on your model init. The updated_at and created_at column will update automatically.

于 2013-07-25T04:59:15.400 回答