python3 django mysql5.5_Django2.1版本不再支持Mysql5.5

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

$coveragerunmanage.pytest--settings=takachiho.settings.testing--pattern="test_*.py"-v2

DEBUG2018-08-0220:02:31,948base619140240725620480ConfiguringRavenforhost:None

INFO2018-08-0220:02:31,949base619140240725620480Ravenisnotconfigured(loggingisdisabled).Pleaseseethedocumentationformoreinformation.

Creatingtestdatabaseforalias'default'('test_takachiho_temp')...

Operationstoperform:

Synchronizeunmigratedapps:admindocs,django_mptt_admin,messages,mptt,raven_contrib_django,staticfiles

Applyallmigrations:admin,alarm,auth,contenttypes,django_celery_beat,locator,metadata,monitor,noise_reductor,request_locator,sessions,utils

Synchronizingappswithoutmigrations:

Creatingtables...

RunningdeferredSQL...

Runningmigrations:

Traceback(mostrecentcalllast):

File"/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py",line83,in_execute

returnself.cursor.execute(sql)

File"/usr/local/lib/python3.6/site-packages/django/db/backends/mysql/base.py",line71,inexecute

returnself.cursor.execute(query,args)

File"/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py",line250,inexecute

self.errorhandler(self,exc,value)

File"/usr/local/lib/python3.6/site-packages/MySQLdb/connections.py",line50,indefaulterrorhandler

raiseerrorvalue

File"/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py",line247,inexecute

res=self._query(query)

File"/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py",line412,in_query

rowcount=self._do_query(q)

File"/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py",line375,in_do_query

db.query(q)

File"/usr/local/lib/python3.6/site-packages/MySQLdb/connections.py",line276,inquery

_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,结果如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

Operationstoperform:

Synchronizeunmigratedapps:admindocs,django_mptt_admin,messages,mptt,raven_contrib_django,staticfiles

Applyallmigrations:admin,alarm,auth,contenttypes,django_celery_beat,locator,metadata,monitor,noise_reductor,request_locator,sessions,utils

Synchronizingappswithoutmigrations:

b'SHOW FULL TABLES'

Creatingtables...

RunningdeferredSQL...

Runningmigrations:

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(mostrecentcalllast):

File"/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py",line83,in_execute

returnself.cursor.execute(sql)

File"/usr/local/lib/python3.6/site-packages/django/db/backends/mysql/base.py",line71,inexecute

returnself.cursor.execute(query,args)

File"/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py",line250,inexecute

self.errorhandler(self,exc,value)

File"/usr/local/lib/python3.6/site-packages/MySQLdb/connections.py",line50,indefaulterrorhandler

raiseerrorvalue

File"/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py",line247,inexecute

res=self._query(query)

File"/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py",line413,in_query

rowcount=self._do_query(q)

File"/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py",line376,in_do_query

db.query(q)

File"/usr/local/lib/python3.6/site-packages/MySQLdb/connections.py",line276,inquery

_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)

1

2

3

4

5

mysql>CREATETABLE`django_migrations`(`id`integerAUTO_INCREMENTNOT NULLPRIMARY KEY,`app`varchar(255)NOT NULL,`name`varchar(255)NOT NULL,`applied`datetimeNOT NULL);

QueryOK,0rowsaffected(0.00sec)

mysql>CREATETABLE`django_migrations`(`id`integerAUTO_INCREMENTNOT NULLPRIMARY KEY,`app`varchar(255)NOT NULL,`name`varchar(255)NOT NULL,`applied`datetime(6)NOT NULL);

ERROR1064(42000):YouhaveanerrorinyourSQLsyntax;checkthemanualthatcorrespondstoyourMySQLserverversionfortherightsyntaxtousenear'(6) NOT NULL)'atline1

但是为啥之前好好地,突然就有问题了呢?唉,这里浪费的时间就不说了,总之我后来终于顿悟发觉是依赖更新了导致的。因为 requirements.txt 添加了一个新的 package ,里面所有的东西都重新安装过(新建的 Docker image),然后因为我们的 pip 没有锁版本,最近 Django 发布 2.1,CI 的 image 由默认的 2.0 版本升级到 2.1 了。

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

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

1

CREATETABLE`django_migrations`(`id`integerAUTO_INCREMENTNOT NULLPRIMARY KEY,`app`varchar(255)NOT NULL,`name`varchar(255)NOT NULL,`applied`datetimeNOT NULL)

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

1

CREATETABLE`django_migrations`(`id`integerAUTO_INCREMENTNOT NULLPRIMARY 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 的版本是个坑,有点想用 Pipenv 了

思路不清晰,随着自己“无根据的猜测”去排查浪费了时间(pip list 都是在 CI 打印出来的,认真看看就能发现)

自己用的项目就应该好好的 watch,看 Changelog!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值