前言
SQLAlchemy 版本:1.2
Mysql 这种数据库不支持 json 对象的存储,但是开发过程中又确实有这种需求。一种思路是使用字符串来存储该对象,入库时序列化,出库时反序列化。在业务代码中维护数据转换又很大的思维负担,还容易出错,因此这个功能的实现自然而然落在了 ORM 里。
自定义类型
SQLAlchemy 支持自定义处理函数,继承 TypeDecorator
即可很方便得到用户自定义类型。代码如下:
1 | import json |
这段代码扩展了原生的 String 类型,在处理 bind param 时将其序列化,在从数据库取出结果后反序列化。还有其他的可定义的步骤,如 process_literal_param
,定义了如何处理一个 literal param。但是这里我用不到,就不定义了。
定义 Model
这里我踩到一个坑,结合 Model 定义来趟坑。
1 | # 定义数据库 |
以下为打印出来的建表语句,可以看出,default
参数不影响建表语句,server_default
会影响,text()
函数将后面的 server_default
直接放在生成 SQL 对应位置,不使用该函数则会对 server_default
进行对应的转义。
1 | CREATE TABLE users ( |
下面生成一个数据
1 | from sqlalchemy.orm import sessionmaker |
print
的输出是
1 | ([u'this is default'], <type 'list'>) |
可以看到,default
在写入数据库的时候,是作为 bind_param 传入的,因此要经过 process_bind_param
的处理。如果我们定义的 process_bind_param
期望的输入是一个数组或字典,那么 default
也要赋值一个数组或字典,而不是已经序列化之后的字符串。