sqlalchemy-自定义数据类型
目录
前言
sqlalchemy包含了mysql支持的所有的数据类型,我们平时的使用基本上都能够满足了。
但是,有一种情况比较特殊,就是mysql不能存储json数据,自然,sqlalchemy也没有对应json的数据类型。
这次在项目中,我需要在mysql中存储一个结构化的数据:JSON数据。那么,能实现吗?
实现原理
是可以实现的,因为sqlalchemy提供了一个类:TypeDecorator。这个类可以定义某个现存的数据类型的行为,文档原话:
Allows the creation of type which add addtional functionality to an existing type
TypeDecorator提供了两个方法作为存入mysql前 与 从mysql取出数据后 的两个操作,有点钩子函数的意思。分别为:
def process_bind_param(self, value, dialect):
pass
def process_result_value(self, value, dialect):
pass
正是通过这两个函数改变了基本类型的表现方式。可以看下面的例子
案例
为一个数据类型添加前缀
from sqlalchemy import TypeDecorator, String
class MyType(TypeDecorator):
impl = String # impl必须存在,指定基于的数据类型
def process_bind_param(self, value, dialect):
return "PREFIX:" + value
def process_result_value(self, value, dialect):
return value[7:]
由于它可以改变数据行为,我就想到了我们可以基于String或者Text类型来实现json数据,配合json包的dumps和loads即可。具体实现代码如下:
import json
from sqlalchemy import Text, TypeDecorator
class Json(TypeDecorator):
impl = Text
def process_bind_param(self, value, dialect):
return json.dumps(value)
def process_result_value(self, value, dialect):
if value is None:
return None
else:
return json.loads(value)
这就实现了一个Json数据类型的定义,我们使用它时,就像使用Text、String这个类型的形式是一样的。