django2.1 mysql5.0_Django2.1版本不再支持Mysql5.5

博客讲述了作者在使用Django2.1时遇到的问题,由于Django2.1版本的migrations在创建表格时使用了datetime(6)字段,而在MySQL5.5中不支持此语法,导致数据库迁移失败。这个问题在Django的更新日志中有提及,但作者在升级时未注意到。通过排查和测试,作者确定问题源于Django版本升级和MySQL版本不兼容。解决方案是将数据库升级到支持datetime(6)的版本或者回退Django到兼容的版本。

好吧,这其实并不是啥高深的东西。如果你升级之前老老实实看了 Changelog,就肯定不会跟我这么倒霉了。

这件事情还是今天我们的 Gitlab CI 莫名其妙挂掉了。日志如下:

$ coverage run manage.py test --settings=takachiho.settings.testing --pattern="test_*.py" -v 2

DEBUG 2018-08-02 20:02:31,948 base 619 140240725620480 Configuring Raven for host: None

INFO 2018-08-02 20:02:31,949 base 619 140240725620480 Raven is not configured (logging is disabled). Please see the documentation for more information.

Creating test database for alias 'default' ('test_takachiho_temp')...

Operations to perform:

Synchronize unmigrated apps: admindocs, django_mptt_admin, messages, mptt, raven_contrib_django, staticfiles

Apply all migrations: admin, alarm, auth, contenttypes, django_celery_beat, locator, metadata, monitor, noise_reductor, request_locator, sessions, utils

Synchronizing apps without migrations:

Creating tables...

Running deferred SQL...

Running migrations:

Traceback (most recent call last):

File "/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py", line 83, in _execute

return self.cursor.execute(sql)

File "/usr/local/lib/python3.6/site-packages/django/db/backends/mysql/base.py", line 71, in execute

return self.cursor.execute(query, args)

File "/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py", line 250, in execute

self.errorhandler(self, exc, value)

File "/usr/local/lib/python3.6/site-packages/MySQLdb/connections.py", line 50, in defaulterrorhandler

raise errorvalue

File "/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py", line 247, in execute

res = self._query(query)

File "/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py", line 412, in _query

rowcount = self._do_query(q)

File "/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py", line 375, in _do_query

db.query(q)

File "/usr/local/lib/python3.6/site-packages/MySQLdb/connections.py", line 276, in query

_mysql.connection.query(self, query)

_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(6) NOT NULL)' at line 1")

其中:

本地运行是 ok 的

master 分支的CI是 ok 的

挂掉的那个分支添加了新的依赖 anytree

大量被浪费的时间……

一开始我怀疑是代码的变更导致生成了不合法的 SQL,于是仔细看了一遍 migrations,没发现什么异常(这是白费功夫,因为显然 migrations 还没开始执行就挂了)。

于是尝试打印出来执行的 SQL,因为 CI 是在 docker 跑的,于是我直接进入 docker ,修改 SQL syntax error 的那个文件,打印出来 q

,结果如下:

Operations to perform:

Synchronize unmigrated apps: admindocs, django_mptt_admin, messages, mptt, raven_contrib_django, staticfiles

Apply all migrations: admin, alarm, auth, contenttypes, django_celery_beat, locator, metadata, monitor, noise_reductor, request_locator, sessions, utils

Synchronizing apps without migrations:

b'SHOW FULL TABLES'

Creating tables...

Running deferred SQL...

Running migrations:

b'SHOW FULL TABLES'

b'CREATE TABLE `django_migrations` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `app` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `applied` datetime(6) NOT NULL)'

Traceback (most recent call last):

File "/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py", line 83, in _execute

return self.cursor.execute(sql)

File "/usr/local/lib/python3.6/site-packages/django/db/backends/mysql/base.py", line 71, in execute

return self.cursor.execute(query, args)

File "/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py", line 250, in execute

self.errorhandler(self, exc, value)

File "/usr/local/lib/python3.6/site-packages/MySQLdb/connections.py", line 50, in defaulterrorhandler

raise errorvalue

File "/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py", line 247, in execute

res = self._query(query)

File "/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py", line 413, in _query

rowcount = self._do_query(q)

File "/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py", line 376, in _do_query

db.query(q)

File "/usr/local/lib/python3.6/site-packages/MySQLdb/connections.py", line 276, in query

_mysql.connection.query(self, query)

_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(6) NOT NULL)' at line 1")

我把这行代码拷贝到本机的 Mysql 执行,没问题啊(废话,我为啥要这么做啊…… Docker里面的 mysql 和我电脑上的明显版本不一样)。

于是在 Docker 的 mysql 执行,嗯,确实语法错误。而且我确认了是支持 datetime

不支持 datetime(6)

mysql> CREATE TABLE `django_migrations` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `app` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `applied` datetime NOT NULL);

Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE `django_migrations` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `app` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `applied` datetime(6) NOT NULL);

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(6) NOT NULL)' at line 1

但是为啥之前好好地,突然就有问题了呢?唉,这里浪费的时间就不说了,总之我后来终于顿悟发觉是依赖更新了导致的。因为 requirements.txt

添加了一个新的 package ,里面所有的东西都重新安装过(新建的 Docker image),然后因为我们的 pip 没有锁版本,最近 Django 发布 2.1,CI 的 image 由默认的 2.0 版本升级到 2.1 了。

我用两个 Django 版本跑测试,打印出来 SQL 日志,发现两个版本生成的 SQL 语法确实不一样。

其中,Django2.0 创建 migrations 生成的 SQL 如下:

CREATE TABLE `django_migrations` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `app` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `applied` datetime NOT NULL)

然后当前 pip 默认版本的 Django 2.1 创建 migrations 生成的 SQL 如下:

CREATE TABLE `django_migrations` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `app` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `applied` datetime(6) NOT NULL)

唯一的不同就是 datetime

变成了 datetime(6)

而我们的 CI image 用的是 python-3.6-jessie

,apt-get 安装的 mysql 版本是 5.5,不支持 datetime(6)

这种语法。

但是好好的 migrations 咋说更新就更新了呢? I blame Django。

然后我就发现人家明确说不支持 Mysql 5.5 了: Dropped support for MySQL 5.5

好吧,算我活该。

反思:

pip list

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值