GINO JSONB支持实战:PostgreSQL高级数据类型操作指南

GINO JSONB支持实战:PostgreSQL高级数据类型操作指南

【免费下载链接】gino python-gino/gino: 是一个基于 Python 的 ORM 框架,支持异步 I/O 和 PostgreSQL、MySQL、SQLite 等多种数据库。该项目提供了一个简单易用的 API,可以方便地实现数据库的查询和操作,同时支持多种数据库和异步 I/O。 【免费下载链接】gino 项目地址: https://gitcode.com/gh_mirrors/gi/gino

GINO是一个基于Python的异步ORM框架,为PostgreSQL数据库提供了强大的JSONB数据类型支持。本文将详细介绍如何在GINO中高效使用JSONB类型,帮助开发者充分利用PostgreSQL的高级数据特性,构建灵活的数据模型。

GINO ORM框架介绍

为什么选择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字段profileUser模型,并定义了两个JSON属性agebirthday,它们将存储在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类型数据库类型
StringPropertystrstringtext
IntegerPropertyintnumberint
BooleanPropertyboolbooleanboolean
DateTimePropertydatetimestringtext
ObjectPropertydictobjectJSON
ArrayPropertylistarrayJSON

在查询中使用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;

GINO连接池架构

高级功能: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类型提供了全面而直观的支持,通过本文介绍的方法,开发者可以:

  1. 轻松定义和使用JSONB字段及属性
  2. 利用丰富的JSON属性类型处理不同数据
  3. 在查询中直接使用JSON属性进行过滤和排序
  4. 通过钩子函数自定义JSON属性的行为
  5. 为JSON属性创建索引提升查询性能

通过GINO的JSONB支持,开发者可以充分利用PostgreSQL的高级数据特性,构建更加灵活和高效的异步应用。更多详细信息请参考官方文档docs/how-to/json-props.rst

要开始使用GINO,请克隆仓库:

git clone https://gitcode.com/gh_mirrors/gi/gino

【免费下载链接】gino python-gino/gino: 是一个基于 Python 的 ORM 框架,支持异步 I/O 和 PostgreSQL、MySQL、SQLite 等多种数据库。该项目提供了一个简单易用的 API,可以方便地实现数据库的查询和操作,同时支持多种数据库和异步 I/O。 【免费下载链接】gino 项目地址: https://gitcode.com/gh_mirrors/gi/gino

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值