GINO JSONB支持实战:PostgreSQL高级数据类型操作指南
GINO是一个基于Python的异步ORM框架,为PostgreSQL数据库提供了强大的JSONB数据类型支持。本文将详细介绍如何在GINO中高效使用JSONB类型,帮助开发者充分利用PostgreSQL的高级数据特性,构建灵活的数据模型。
为什么选择JSONB类型?
JSONB(JSON Binary)是PostgreSQL提供的一种二进制JSON数据类型,相比普通JSON类型具有以下优势:
- 支持索引,大幅提升查询性能
- 提供丰富的JSON操作函数
- 存储效率更高,支持数据验证
- 适合存储半结构化数据和灵活模式
GINO框架通过直观的API将JSONB功能集成到异步数据访问层,让开发者可以轻松处理复杂数据结构。
快速开始:在GINO中定义JSONB字段
使用GINO定义包含JSONB字段的模型非常简单,只需导入PostgreSQL的JSONB类型并在模型中声明:
from gino import Gino
from sqlalchemy.dialects.postgresql import JSONB
db = Gino()
class User(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
profile = db.Column(JSONB, nullable=False, server_default="{}")
# JSON属性定义
age = db.IntegerProperty()
birthday = db.DateTimeProperty()
上述代码创建了一个包含JSONB字段profile的User模型,并定义了两个JSON属性age和birthday,它们将存储在profile字段中。
JSON属性的基本操作
GINO的JSON属性可以像普通模型字段一样使用,提供了直观的访问方式:
创建记录
# 创建包含JSON属性的用户记录
user = await User.create(
name="Alice",
age=30,
birthday=datetime(1993, 5, 15)
)
访问属性
# 直接访问JSON属性
print(user.age) # 输出: 30
print(user.birthday) # 输出: 1993-05-15 00:00:00
更新属性
# 更新JSON属性
user.age = 31
await user.update().apply()
支持的JSON属性类型
GINO提供了多种JSON属性类型,满足不同数据需求:
| JSON属性类型 | Python类型 | JSON类型 | 数据库类型 |
|---|---|---|---|
| StringProperty | str | string | text |
| IntegerProperty | int | number | int |
| BooleanProperty | bool | boolean | boolean |
| DateTimeProperty | datetime | string | text |
| ObjectProperty | dict | object | JSON |
| ArrayProperty | list | array | JSON |
在查询中使用JSON属性
GINO允许直接在查询中使用JSON属性,自动转换为PostgreSQL的JSONB操作:
# 查询年龄大于18的用户
adults = await User.query.where(User.age > 18).gino.all()
# 查询特定生日之后出生的用户
from datetime import datetime
millennials = await User.query.where(
User.birthday > datetime(1980, 1, 1)
).gino.all()
GINO会自动将上述查询转换为PostgreSQL的JSONB操作,例如:
SELECT users.id, users.name, users.profile
FROM users
WHERE CAST((users.profile ->> 'age') AS INTEGER) > 18;
高级功能:JSON属性钩子
GINO提供了钩子函数,可以在JSON属性的读写过程中进行自定义处理:
实例级钩子
class User(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
profile = db.Column(JSONB, nullable=False, server_default="{}")
age = db.IntegerProperty()
@age.before_set
def age(self, val):
# 设置前处理:确保年龄为正数
return max(0, val)
@age.after_get
def age(self, val):
# 获取后处理:返回年龄加1
return val + 1 if val is not None else None
类级表达式钩子
class User(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
profile = db.Column(JSONB, nullable=False, server_default="{}")
height = db.JSONProperty()
@height.expression
def height(cls, exp):
# 自定义SQL表达式:将高度转换为FLOAT类型
return exp.cast(db.Float)
在JSON属性上创建索引
为提升查询性能,可以在JSON属性上创建索引:
class User(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
profile = db.Column(JSONB, nullable=False, server_default="{}")
age = db.IntegerProperty()
@db.declared_attr
def age_idx(cls):
# 创建年龄索引
return db.Index("age_idx", cls.age)
这将生成以下SQL:
CREATE INDEX age_idx ON users (CAST(profile ->> 'age' AS INTEGER));
注意:Alembic目前不支持自动生成函数索引的迁移脚本,需要手动编辑迁移文件。
总结
GINO框架为PostgreSQL的JSONB类型提供了全面而直观的支持,通过本文介绍的方法,开发者可以:
- 轻松定义和使用JSONB字段及属性
- 利用丰富的JSON属性类型处理不同数据
- 在查询中直接使用JSON属性进行过滤和排序
- 通过钩子函数自定义JSON属性的行为
- 为JSON属性创建索引提升查询性能
通过GINO的JSONB支持,开发者可以充分利用PostgreSQL的高级数据特性,构建更加灵活和高效的异步应用。更多详细信息请参考官方文档docs/how-to/json-props.rst。
要开始使用GINO,请克隆仓库:
git clone https://gitcode.com/gh_mirrors/gi/gino
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考





