我遇到了Python,MySQL和创建一个包含两个时间戳列的表的问题。
通过Python并使用MySQLDB执行以下SQL:
CREATE TABLE test_db.test_with_two_datetime_columns (
`first_datetime_field` TIMESTAMP(6) NOT NULL DEFAULT 0,
`second_datetime_field` TIMESTAMP(6) NOT NULL DEFAULT 0
) ENGINE=InnoDB
我收到错误(1067, Invalid default value for 'first_datetime_field')
,而我可以在MySQL
CLI中轻松触发以下相等命令:
$ mysql -h localhost
> CREATE TABLE test_db.test_with_two_datetime_columns (
`first_datetime_field` TIMESTAMP(6) NOT NULL DEFAULT 0,
`second_datetime_field` TIMESTAMP(6) NOT NULL DEFAULT 0
) ENGINE=InnoDB;
Query OK, 0 rows affected (0.01 sec)
同样通过Sequel Pro,上面的命令执行得很好。
所以我猜测问题出在MySQLDB
(akak。MySQL-Python
),但这看起来很奇怪
我正在使用MySQL 5.6.17
,MySQL-Python 1.2.5
和Python 2.7
。
答案 0 :(得分:1)
我使用https://stackoverflow.com/a/22860449/1362628中的想法解决了问题,将默认值更改为null
并允许该条目为null
。
CREATE TABLE test_db.test_with_two_datetime_columns (
`first_datetime_field` TIMESTAMP(6) NULL DEFAULT NULL,
`second_datetime_field` TIMESTAMP(6) NULL DEFAULT NULL
) ENGINE=InnoDB""")
现在它工作正常。但问题是,这些字段都不能参与primary key
,因为它们可以包含null
。
更新
事实证明,使用SELECT @@session.sql_mode
我发现MySQLDB上的包装器代码正在将sql_mode
设置为TRADITIONAL
。 TRADITIONAL
展开为STRICT_TRANS_TABLES, STRICT_ALL_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, TRADITIONAL, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION
,其中NO_ZERO_IN_DATE
和NO_ZERO_DATE
出现上述错误。从长远来看,我更倾向于上述解决方案,缺少的值表示为null。
答案 1 :(得分:0)
这里可能有几个问题。
我的猜测是,MySQLDB不会将整数0识别为DateTime或Timestamp类型的列的有效值。恕我直言,MySQL也不应该,但确实如此。您可以在服务器级别更改该行为。请参阅NO_ZERO_DATE。
如果我在你的鞋子里,我会尝试这些方法。
CREATE TABLE test_with_two_datetime_columns (
`first_datetime_field` TIMESTAMP(6) not null default '0000-00-00 00:00:00',
`second_datetime_field` TIMESTAMP(6) not null default '0000-00-00 00:00:00',
primary key (first_datetime_field, second_datetime_field)
) ENGINE=InnoDB ;
这些默认值实际上与此上下文中的整数0相同。一种替代方法是将两列默认为时间戳的最小值,'1970-01-01 00:00:01'。另一种方法是将一列默认为current_timestamp。 (不是两列; MySQL认为这是一个错误。)
就个人而言,我不喜欢“所有球”的时间戳。 “所有球”是时间戳奇怪 - 词汇上,它不在“1970-01-01 00:00:01”UTC到“2038-01-19 03:14:07”UTC的定义范围内。但你必须找到自己的舒适程度。