使用 SQLAlchemy 和 PostgreSQL 过滤 JSON 类型字段

DDD
发布: 2025-09-29 19:19:20
原创
605人浏览过

使用 sqlalchemy 和 postgresql 过滤 json 类型字段

摘要:本文档介绍了如何使用 SQLAlchemy 和 PostgreSQL 过滤 JSON 类型字段中的数据。我们将探讨如何使用 cast() 函数将 JSON 类型转换为 JSONB 类型,并利用 has_any() 方法来高效地筛选出包含特定数组元素的记录。此外,还讨论了 JSONPath 的使用限制以及 SQLAlchemy 中 JSON 操作符的转换规则。

在使用 PostgreSQL 数据库时,经常会遇到存储 JSON 格式数据的情况。当需要根据 JSON 字段中的特定属性进行过滤时,可以使用 SQLAlchemy 来构建相应的查询语句。本文将详细介绍如何使用 SQLAlchemy 1.4 版本以及 PostgreSQL 9.6 或更高版本来过滤 JSON 类型字段。

JSON 数据准备

假设我们有一个名为 test_table 的表,其中包含一个 attributes 列,该列存储 JSON 数据。表结构如下:

 Column     |          Type          |
------------+------------------------+
 id         | integer                |
 attributes | json                   |
登录后复制

表中的数据示例如下:

 id |    attributes
----+----------------------------
  1 | {"a": 1, "b": ["b1","b2"]}
  2 | {"a": 2, "b": ["b3"]}
  3 | {"a": 3}
登录后复制

现在,我们需要筛选出 attributes 字段中 b 属性包含 "b1" 或 "b3" 的记录。

使用 cast() 和 has_any() 进行过滤

在 PostgreSQL 中,可以使用 ?| 操作符来检查 JSON 数组是否包含指定数组中的任何元素。在 SQLAlchemy 中,?| 操作符对应于 has_any() 方法。要使用 has_any() 方法,首先需要将 JSON 类型转换为 JSONB 类型,因为 has_any() 方法是 JSONB 类型的比较器方法。

Find JSON Path Online
Find JSON Path Online

Easily find JSON paths within JSON objects using our intuitive Json Path Finder

Find JSON Path Online30
查看详情 Find JSON Path Online

以下是使用 SQLAlchemy 实现上述过滤的示例代码:

from sqlalchemy import create_engine, Column, Integer, String, JSON, cast, select
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy.dialects.postgresql import JSONB

# 定义模型
Base = declarative_base()

class TestTable(Base):
    __tablename__ = 'test_table'
    id = Column(Integer, primary_key=True)
    attributes = Column(JSON)

    def __repr__(self):
        return f"<TestTable(id={self.id}, attributes={self.attributes})>"

# 创建数据库连接
engine = create_engine('postgresql://user:password@host:port/database')
Base.metadata.create_all(engine)

# 创建会话
Session = sessionmaker(bind=engine)
session = Session()

# 准备过滤条件
arr = ["b1", "b3"]

# 构建查询语句
stmt = select(TestTable).where(cast(TestTable.attributes["b"], JSONB).has_any(arr))

# 执行查询
results = session.execute(stmt).scalars().all()

# 打印结果
for result in results:
    print(result)

# 关闭会话
session.close()
登录后复制

在上面的代码中,我们首先使用 cast() 函数将 attributes["b"] 的类型转换为 JSONB。然后,我们使用 has_any() 方法来检查转换后的 JSONB 数组是否包含 arr 列表中的任何元素。

注意事项

  • 确保 SQLAlchemy 版本为 1.4 或更高版本,PostgreSQL 版本为 9.6 或更高版本。
  • has_any() 方法只能用于 JSONB 类型,因此需要使用 cast() 函数进行类型转换。
  • 如果需要使用更灵活的 JSON 查询方式,可以考虑使用 JSONPath。但是,JSONPath 需要 PostgreSQL 12.0 或更高版本。

SQLAlchemy JSON 操作符转换规则

SQLAlchemy 将 PostgreSQL 的 JSON 操作符转换为相应的 Python 方法。以下是一些常见的转换规则:

PostgreSQL 操作符 SQLAlchemy 方法
-> __getitem__()
->> __getitem__()
? has_key()
?| has_any()
?& has_all()
@> contains()
<@ contained_by()

更多详细的转换规则可以参考 SQLAlchemy 官方文档或相关 issue。

总结

本文介绍了如何使用 SQLAlchemy 和 PostgreSQL 过滤 JSON 类型字段中的数据。通过使用 cast() 函数将 JSON 类型转换为 JSONB 类型,并利用 has_any() 方法,可以高效地筛选出包含特定数组元素的记录。同时,我们也讨论了 JSONPath 的使用限制以及 SQLAlchemy 中 JSON 操作符的转换规则。希望本文能够帮助你更好地使用 SQLAlchemy 和 PostgreSQL 处理 JSON 数据。

以上就是使用 SQLAlchemy 和 PostgreSQL 过滤 JSON 类型字段的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号