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这个类型的形式是一样的。