如何使用 sqlalchemy 在 mysql 中设置 DEFAULT ON UPDATE CURRENT_TIMESTAMP?

Posted

技术标签:

【中文标题】如何使用 sqlalchemy 在 mysql 中设置 DEFAULT ON UPDATE CURRENT_TIMESTAMP?【英文标题】:How to set DEFAULT ON UPDATE CURRENT_TIMESTAMP in mysql with sqlalchemy? 【发布时间】:2011-08-09 06:41:19 【问题描述】:

我正在用 sqlalchemy 创建表。

user = Table('users', Metadata,
Column('datecreated', TIMESTAMP,                                  
            server_default=text('CURRENT_TIMESTAMP')),            
Column('datemodified', TIMESTAMP,                                 
               server_onupdate=text('CURRENT_TIMESTAMP')),
)

但这不会设置DEFAULT ON UPDATE CURRENT_TIMESTAMP

我检查了How do you get SQLAlchemy to override mysql "on update CURRENT_TIMESTAMP",但对于文字,我需要在创建表定义中连接它。

【问题讨论】:

对于像我这样的人可能最终会在 Postgres 上寻找相同的功能:解决方案非常不同,并在讨论 here 【参考方案1】:

你可以劫持 server_default 来设置 ON UPDATE:

Column('datemodified', TIMESTAMP,
       server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))

这会生成以下列条目:

datemodified TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

但是,Mchl 的回答仍然适用:表中只能有一个自动 TIMESTAMP 列 (http://dev.mysql.com/doc/refman/5.5/en/timestamp.html)

还要注意列的顺序很重要!如果您有一个没有 DEFAULT 和 ON UPDATE 修饰符的 TIMESTAMP 列,并且它是表中的第一个 TIMESTAMP 列, 它会自动设置为 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP。 (http://dev.mysql.com/doc/refman/5.5/en/timestamp.html)

所以这很好:

Column('datemodified', TIMESTAMP,
       server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))
Column('datecreated', TIMESTAMP)

虽然不是这样:

Column('datecreated', TIMESTAMP)
Column('datemodified', TIMESTAMP,
       server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))

为了在行的第一次输入期间将 `datecreated' 设置为当前时间,只需将其值显式设置为 NULL。同样,来自http://dev.mysql.com/doc/refman/5.5/en/timestamp.html:

默认情况下,TIMESTAMP 列不是 NULL,不能包含 NULL 值,分配 NULL 分配当前时间戳

【讨论】:

这是唯一对我有用的方法,server_onupdate=text('CURRENT_TIMESTAMP') 的任何组合都不能解决问题。如果您使用的是 mysql 5.6+(到目前为止,大多数人应该是),这应该是公认的答案。【参考方案2】:

如果您使用的是 MySQL 5.6 或更高版本,请向下滚动以获取相关答案。旧版本的用户,请阅读这篇。


直到 MySQL 5.6。在一张表中,您只能有一个“自动”TIMESTAMP 列。

发件人:http://dev.mysql.com/doc/refman/5.5/en/timestamp.html

对于表中的一个 TIMESTAMP 列,您可以分配当前 时间戳作为默认值和自动更新值。这是 可以将当前时间戳设为默认值 初始化列,用于自动更新值,或两者兼而有之。它不是 可以将当前时间戳作为一个的默认值 列和另一列的自动更新值。

【讨论】:

如果我写user = Table('users', Metadata, Column('datecreated', DateTime), Column('datemodified', TIMESTAMP, server_onupdate=text('CURRENT_TIMESTAMP')), ) 那么它将适用于DEFAULT ON UPDATE CURRENT_TIMESTAMP? 我检查了这个例子,但它没有设置 DEFAULT ON UPDATE CURRENT_TIMESTAMP。当我们用于单列时。 :( 如果这不可能,请告诉我如何在 sqlalchemy 中设置 onupdate 触发器? 对于 mysql 5.6 的追随者,不要停在这里,下面有一个很好的答案...... @domoarrigato:我已将其添加到答案的顶部。【参考方案3】:

这适用于 Mysql 8

sa.Column('created_at', sa.TIMESTAMP, server_default=func.now()),
sa.Column('updated_at', sa.TIMESTAMP, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))

由于某种原因,server_onupdate 选项不起作用。

【讨论】:

【参考方案4】:
from sqlalchemy.sql import func

Column('datemodified',
       TIMESTAMP,                                 
       server_onupdate=text(
           ' ON UPDATE '.join([str(func.current_timestamp())] * 2)))

这样你就可以使用 SQLAlchemy 的内部 func.current_timestamp() 函数了。

【讨论】:

【参考方案5】:

如果您想要的只是在 MySQL 中更新 CURRENT_TIMESTAMP 时的 DEFAULT CURRENT_TIMESTAMP,那么只需将 sqlalchemy 中的 TIMESTAMP 列设置为不可为空即可

Column(TIMESTAMP, nullable=False)

【讨论】:

不,这不起作用

以上是关于如何使用 sqlalchemy 在 mysql 中设置 DEFAULT ON UPDATE CURRENT_TIMESTAMP?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 sqlalchemy 在 mysql 中设置 DEFAULT ON UPDATE CURRENT_TIMESTAMP?

每当 MySQL 抛出警告时,我如何通知 sqlalchemy 引发错误?

使用Flask SQLAlchemy从SQLite切换到MySQL

如何在 SQLAlchemy 中定义无符号整数

如何使用 mysqlconnector 获取 sqlalchemy.create_engine 以使用 mysql_native_password 进行连接?

如何使用 Python 在 AWS Lambda 上运行 SQLAlchemy