Django2.1版本不再支持Mysql5.5

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

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

其中:

  1. 本地运行是 ok 的
  2. master 分支的CI是 ok 的
  3. 挂掉的那个分支添加了新的依赖 anytree

大量被浪费的时间……

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

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

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

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

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

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

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

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

唯一的不同就是 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 好吧,算我活该。

反思:

  1. 测试环境和开发环境不一致是个坑
  2. 不锁定 pip 的版本是个坑,有点想用 Pipenv 了
  3. 思路不清晰,随着自己“无根据的猜测”去排查浪费了时间(pip list 都是在 CI 打印出来的,认真看看就能发现)
  4. 自己用的项目就应该好好的 watch,看 Changelog!
 

黄金年代的辉煌和焦虑

最近失眠比较严重,看了一个电影,伍迪艾伦的《Midnight in Paris》。前段时间看过他的《Vicky Cristina Barcelona》,很不喜欢这部电影,我不明白他想说什么。《Vicky Cristina Barcelona》将爱描述的非常轻浮,出轨在伍迪艾伦里面的电影是在太简单了,里面的男人和女人要么就是虚伪的保守者,要么就是放荡的花花公子之类,电影背景乐一直再重复,让人很烦躁。有点跑题了,还是说会《Midnight in Paris》吧,这部电影和《Vicky Cristina Barcelona》有一些共同点:都是在如画的欧洲拍的;都有出轨。甚至有点《The Grand Budapest》的感觉。我看了一下演员表,男主角 Owen Wilson 竟然在《The Grand Budapest》饰演了一个配角,还真是巧。

右一是 Owen Wilson

影片讲述的是男主角 Gil 和未婚妻 Inez 一家人来欧洲旅行,Gil 滔滔不绝巴黎是多么美丽,如果留在这里该多好,但是遭到 Inez 妈妈的反对。后来在餐厅他们碰巧遇上了保罗夫妇。于是接下来的行程就被未婚妻安排了跟保罗夫妇一起,品酒,舞会,自驾去凡尔赛宫。保罗是个非常爱掉书袋的讨厌鬼,于是 Gil 成了这趟旅行中最不高兴的一个人。在一天晚上未婚妻 Inez 决定跟保罗夫妇去跳舞,Gil 决定自己回家。回家途中却迷了路,这时候来了一辆车,里面的人快活的叫他快上车,Gil 就这样不明不白的上了车,去了一个聚会上。这时候高潮来了,在聚会上一个男人竟然自我介绍是 Fitzgerald!男人怀中的女人是 Zelda Fitzgerald!不可思议的事情接连发生,弹琴的人竟然是 Cole Porter。Fitzgerald 将 Gil 介绍给了 Hemingway,Hemingway 答应让 Gertrude 帮他批改小说草稿。

这是 Gil 梦想的  Golden Age,这是一个文学的黄金年代,人们在酒吧里面讨论文学和艺术,酒吧里的人都是一些大名鼎鼎的作家。

然而这个时代也在悄悄告诉他这个时代的名人的烦恼,比如被妻子左右的 Fitzgerald,Heyminway 批评他一个作家应该花时间在写作上。其中 Heymingway 在车里与 Gil 的一段对话非常有趣,Gil 求 Hemingway 看看他的草稿,Hemingway 却说:永远不要让同行评价你的作品,我恨糟糕的写作,如果写得好,我会更加憎恨你,我会嫉妒你。一个作家要宣称自己是世界上最好的作家!这里还有一段有关真爱和恐惧的言论,比较露骨,我直接贴在这里了。

You’ll never write well if you fear dying. Do you?

But it’s something all men before you have done and all men will do.

Have you ever made love to a truly great woman?

And when you make love to her you feel true and beautiful passion and you at least for that moment lose your fear of death.

I believe that love that’s true and real creates a respite from death. All cowardice comes from not loving or not loving well which is the same thing and when the man who is brave and true looks death squarely in the face like some rhino hunters I know or Belmonte who is truly brave, it is because they love with sufficient passion to push death out of their minds till it returns as it does to all men and then you must make really good love again. Think about it.

以前我总觉得,我生活的年代就是“黄金时代”了。我们有互联网,有了8核的处理器,有了超大的内存,有4G网络,有了 Go 语言和 Rust。现在的人们生来就可以享受这一些,不必经历几百年在计算机方面从电子管到大规模集成电路的苦苦探索。世界上的编程语言都有垃圾回收机制,Python 甚至写起来就像英语一样,不再需要自己从一些底层的概念抽象出来。如果没有了计算机和互联网,真不知道我应该怎么生活下去。

但是有时候,我又觉得即使有了这些东西,人们的生活还是太空洞了。看过一本叫《黑客:计算机革命的英雄们》的书,以前,从MIT开始的第一代黑客,大家恪守的都是分享的精神,大家分享彼此的一切,为了使用计算机可以做任何事(将封锁起来计算机不让别人使用视作是资源的浪费)。而黑客文化的没落也是企业家精神的崛起。所有的东西都被商业化了,现在看看我们的周围吧,所谓的技术,在很多方面不过是让人们多看两眼广告,多收集一些用户信息,甚至让有钱的用户享受“个性定价”而已。

如果能像电影里的 Gil 一样,坐在美国的街头,一辆马车把你接到卡马克的湖边小屋,认识一群正在开发《毁灭公爵》的黑客们。那个游戏黑客的“黄金年代”,该多好啊。

影片中还有另一次穿越,Adriana 和 Gil 被一辆马车接走,来到1893年开张的马克西姆餐厅,遇到了超现实主义大师 Dalí!达利给他们介绍 Gauguin,De Gas。几位大师抱怨现在的人们缺乏想象力,他们怀念文艺复兴。这时从 20世界20年代穿越到19世纪90年代的 Adriana 说这是她的梦想的黄金年代,她要永远生活在这里。Gil 说:这不是你的年代,这也不是我的年代。这里没有洗碗机,也没有抗生素,拔牙的时候你会意识到这里没有麻醉剂(Adiana 表示这是什么?)如果你把这个年代当做你的“现在”,那么迟早你会发现有另一个时代才是你的“黄金年代”。你的时代会让你不满意,因为生活本身就是让你不满意的。这是逃避现实与虚幻的精神失常之间的选择。

最后,Gil 回到了2010年,与出轨的未婚妻分手,选择留在巴黎完成自己的小说,这算是放弃了自己对黄金时代的幻想,勇敢的面对现实吧。

黄金时代大概是我们都会对一个无法得到的年代的幻想吧,因为得不到,我们对其美化。我们将自己在现实无法得到的幻想寄托在那个时代。一个时代有一个时代的进步,也有一个时代的焦虑。即使能回到过去也无法摆脱焦虑,你会得到那个时代的焦虑。我们所生活的时代,确实就是最好的时代。

 

程序员如何写PPT

这个世界上有两种文件,一种是二进制文件,一种是文本文件。虽然本质上都是编码成二进制存储在磁盘上,但是文本文件通过编码规则转换成二进制,可以很方便的通过几乎任何程序解码出来。文本文件是给人读的,二进制文件是给机器执行或载入的。所以如果二进制文件拿来给人读,这就很反人类了。像 Office 的 .doc .xls .ppt 就是这么一些反人类的玩意儿。

幸运的是人们发明了 markdown, html 等可以用纯文本表示出复杂的格式。如果是文本文件,很多事情就变得方便了:你可以使用几乎任何浏览程序或者编辑程序打开;你可以使用 git 对这些文件进行版本控制;可以为他们制作一个自动集成的系统(比如格式检查等);纯文本的格式是确定的,只要遵守格式规范来编写,不像是 .ppt 文件被 Keynote 和 PowerPoint 打开,显示效果可能是不同的;最重要的是:你可以使用你最喜欢的 Vim 编辑器编辑他们!配合适用各种类型的插件,你就可以编辑世界上的任何东西——只要它们是文本文件。

这篇文章会介绍一些不使用微软的 PowerPoint 来制作演示文稿的方法,好处呢,就是上面所介绍的那一些(完美的纯文本),坏处呢,就是可能会有一个 build 的过程,无法所见即所得了。

1 使用 gitpitch

这个是最简单的一个,你只要在 Github 上面上传一个 markdown 文件,然后通过这个网站打开,就自动变成一个 Slides 了。只不过你的 markdown 要稍微对 gitpitch 做一下兼容。其实这个我之前在博客分享过,在公司分享过一次 tmux 就是用这个东西做的 Slides 的。

更新一下评论的 Lisp 大神推荐的 Marp,跟这个思路差不多,也是将 markdown 渲染成演示,但是是本地的编辑器,所见即所得。

2 使用 Jupyter

可能做数据方面的同学比较熟悉 Jupyter,这种基于网页的 REPL 比较好的地方就是渲染图表的时候可以直接显示。Jupyter 功能非常强大,直接运行代码、markdown格式、做图表样样都行。做 Slides 展示也很好看。看过一个同事分享的,效果非常不错。使用教程可以参考这篇。(上图亦来自这篇教程)

3 Read the docs

第一次见到有人使用 readthedocs 做分享是在 Raymond 的视频中(上一篇博客提到过)。readthedocs 显示非常简洁,渲染出来的代码块也非常漂亮,在 Chrome 下按 Command + + 就可以放大,效果很好。左侧的可以嵌套的目录正好可以做一个大纲展示。readthedocs 真是简洁又实用,我翻译的一本书也放在上面,效果可以作为参考。

这种方式的一个额外的好处是,随便找一个文件托管服务,比如 S3 bucket 或者 github pages 就可以,然后随便一台电脑就可以打开访问演示。而且这样放在网上访问方便,不会像 .ppt 文件不兼容新版啦等问题,作者如果更改可以一下子同步上去,PPT 这种文件就像泼出去的水,发给别人就再也更新不了了(当然也可以“最终版” “再也不改了” “最后版本” “最最后版本”发给别人哈哈)。缺点就是要学习 sphinx 学习成本可能会高一些。

4 Racket SlideShow

Racket 套件

Racket 套件

这个是我偶然发现的,没有实际用过。安装 Racket 之后竟然出现这么多套件,有游戏,还有一个 SlideShow???看了一下,竟然是用 Racket 代码来写 PPT…… 听说貌似还有不少用户。

Racket源代码

好吧,Lisp 程序员的世界我有点不懂……

另外再赠送一个呗。推荐一个画图的工具,Graphviz。这个有 Python 的封装,可以使用在项目中,也可以直接手写文件画,还蛮好看的。这里有个画 Python 继承关系的例子。可以看下。

miloyip老师画的

我最初知道这个还可以拿来直接当作图工具用是看了 miloyip 老师的推荐,有兴趣可以看一下这个回答:Mac 上最好用的流程图软件是什么?

 

Python 提高对比效率的一个技巧(位运算&)

最近在看 Python epoll howto 的时候,发现里面对比一个 event 是不是某种 EVENT 类型用的是 & 操作符,比如 elif event & select.EPOLLIN 。一开始还以为是写错了,后来想了一下这样确实能起到 == 的作用,只要事件的实际数字值特殊设计的话。

只比较相等的话,只要不存在包含关系就可以。比如最简单的,每一个 bit 的1表示一个类型(这里都以一个 bytes 作例子吧。

上面4个数字分别是1,2,4,8,分别可以表示四种类型。对比的时候,除非两个类型相等,否则都是 0(Flase)。或者可以用下面这种方式,使用两个1,可以表示的类型多一些。

上面这种也可以达到类似的效果。如果存在包含关系的话就不行了,在不相等的情况下依然可能得到非0值。但是如果不是比较相等的情况,而是比较是不是包含,就可以使用这种表示了。比如 Unix 的文件权限系统,用 4 2 1 来表示执行:

如果验证 6 是否有读权限的话也可以用 & :

结果是非0值,表示拥有此权限。

为什么这么写呢,估计是C程序的风格吧,我用 Python 测试了一下性能,& 操作是比 == 效率高的。因为 epoll 这部分的代码是非常频繁的操作,能节省一些性能的话,还是很可观的。

通过反编译发现,其实 & 编译成 Python 字节码是 BINARY_AND ,而 == 是 COMPARE_OP。应该是 BINARY_AND 效率会比 COMPARE_OP 效率高一些吧。

 

 

PyCon2018 Review (Part 2)

最近空闲时间在看 PyCon 的一些分享,2018年的视频好多,不知道啥时候才能看完。这里将一些个人看过比较好的记录一下。上一次的文章在这里:PyCon2018 Review (Part 1)

5. GC再见,GC你好——Instagram Django进程调优案例

当初 Instagram 禁用 GC 的那篇文章发布之后,声名大噪。Zekun Li 在大会上讲了一下 Instagram 在 Python GC 上下的功夫。起先因为 GC 回收循环引用的问题,共享内容用的少,fork 出来的进程会占用很多内存,于是 Instagram 就想办法禁用了 GC,这样可以减少 Copy-on-Write 需要复制的内存,当然禁用了 GC 肯定会有内存泄漏的问题,Instagram 的选择是保证代码质量,避免在代码中使用循环引用。然而虽然项目增长,这样严格的代码质量难以保证,Instagram 又打开了GC。

演讲者听口音应该是大陆人,这个视频有助于对内存的理解,值得一看。

推荐指数:5

演讲者:Zekun Li from Instagram

相关项目:Django, uWSGI

Youtube: Zekun Li – There and Back Again: Disable and re-enable garbage collector at Instagram – PyCon 2018

6. 一份简单的 Pythonic 指南

我见过很多人写的带有“Java味道”的 Python 代码,里面很多复杂的抽象和继承关系;在循环里自己维护下标等行为,实在头疼。这个演讲适用于新手或者从其他语言过来的人,可以快速过一下 Python 的一些不错的特性。对于写了很长时间的 Python 程序员来说,可能用处不大。吐个槽:整天被业务赶着,时间长了危害实在是大,不抽出时间看看自己的工具都有什么不错的功能,就永远不会有什么长进。

演讲者来自微软,是一位女性,比较好懂。

推荐指数:4

演讲者:Nina Zakharenko

相关项目:The Zen of Pythonagithub, freezegun

Youtube: Nina Zakharenko – Elegant Solutions For Everyday Python Problems – PyCon 2018

7. 打一场值得打的仗:Facebook 的 Python 3迁移之路

现在 Facebook 的大多数项目都是运行在 Python3.6.3 上面的,但是到 2014 年,在 Facebook 内部使用 Python3 几乎是不可能的事情,大部分工程师都持 “我们将永远使用 Python2.7 的态度。一小部分人用业余时间驱动了公司向 Python3 迁移,看本篇演讲,学习如何在你的公司打一场值得的仗。变化不会自己发生,必须有人来引导做出改变。在迁移的过程中,作者首先面对的是 Facebook 所有的 build 系统都是针对 Python2.7 的,只好去一个一个修复,兼容 Python3.然后又要面对同事不停地提交 Python2 代码,作者又加入了 pyflake 检查。(一个小技巧,如果你在你们公司装的很权威,那么别人就会以为你在这方面是权威人士)

后来一些项目只是运行了 2to3,没做其他改变,结果导致因此占用内存降低了一半,运行速度提升了 40%。

Educate for the future you want, not the present you have.

美中不足的是,演讲者经常停顿和重复,对于我来说理解起来不是那么简单。

演讲者:Jason Fried

推荐指数:4

相关项目: 2to3, pyflake

Youtube: Jason Fried – Fighting the Good Fight: Python 3 in your organization – PyCon 2018

8. 字典技术的演化

这个视频是 laike9m 上次在线下给我推荐的,同样不是一个今年的 Pycon 视频,但是号称是“质量最高的一个演讲”,回来看了一下,真的很不错。

大家可能都有听说,Python3.6 里面字典的速度和内存都有了提升,同时带来一个副作用:默认有序了。并且这个副作用在 3.7 版本中写入了语言标准。Raymond 这个演讲涉及了字典的很多常见的技术,例如 Key Sharing,Open Addressing,Double Hashing 等,从头到尾展示和这些技术的演化过程、性能和原理等,介绍了 Python 的 dict 从一开始浪费内存、速度慢进化到了今天的甚至对 key lookup 有缓存。Python 基本是运行在字典上面的,即使有时候我们的感知很弱:module 是一个字典,global 是一个字典,Django 是运行在无数的字典上的,所以如果你优化了字典,你就优化了 Python。相比于 Python2.7,如果你不用 AsyncIO,你可能没有特别的理由升级到 Python3.5,但是 Python3.6 提升了 dict 的性能,这就很划算了。新的 dict (compact dict)使用 list 来存储字典的 key(这样空的位置只需要 8bytes 就够了),减少的空间同时也可以加快 hash 表的载入速度。字典还涉及到一些细节问题,比如删除元素,最后的 QA 也有很多干货。

有意思的是,Raymond在2016年就提到:Guido 目前还认为字典的 key 保持插入顺序这个特性还不能被依赖,但是他会被说付的,简直是预测帝啊。

演讲非常搞笑,Raymond 对自己的 Compact Dict 太满意了哈哈哈哈哈。

另外,我之前也花了很多时间研究字典一些相关的问题,看视频之前也可以看一下我写的这两篇博客,可能加深你对字典的理解,我自认为写的还是比较好懂的:《Hash碰撞和解决策略》、《Python 为什么list不能作为字典的key?

演讲者:Raymond Hettinger(资深Python讲师)

推荐指数:5

相关项目:builtin dict

Youtube:

一共找到两个版本,建议都看一下,67分钟版本更早,里面比较轻松,PyCon 那个比较正式,更加条理。不过67分钟版本的后面有很多 QA,也很有价值。

  1. PyCon2017 37分钟版本:Raymond Hettinger Modern Python Dictionaries A confluence of a dozen great ideas PyCon 2017
  2. 2016年的67分钟版本:Modern Dictionaries by Raymond Hettinger

最后赠送一个我最近在听得一个 podcast(macdavid推荐的):teahour ,内容不错,挺丰富的,从区块链到编辑器都有,很适合程序员。