【问题标题】:SQLAlchemy JSON column - how to perform a contains querySQLAlchemy JSON 列 - 如何执行包含查询
【发布时间】:2017-01-21 01:37:07
【问题描述】:

我在mysql(5.7.12)中有下表:

class Story(db.Model):
    sections_ids = Column(JSON, nullable=False, default=[])

sections_ids 基本上是一个整数列表 [1, 2, ...,n]。 我需要获取sections_ids包含X的所有行。 我尝试了以下方法:

stories = session.query(Story).filter(
        X in Story.sections_ids
    ).all()

但它会抛出:

NotImplementedError: Operator 'contains' is not supported on this expression

【问题讨论】:

    标签: python mysql json sqlalchemy


    【解决方案1】:

    使用JSON_CONTAINS(json_doc, val[, path]):

    from sqlalchemy import func
    
    # JSON_CONTAINS returns 0 or 1, not found or found. Not sure if MySQL
    # likes integer values in WHERE, added == 1 just to be safe
    session.query(Story).filter(func.json_contains(Story.section_ids, X) == 1).all()
    

    当您在顶层搜索数组时,您不需要提供路径。或者,从 8.0.17 开始,您可以使用 value MEMBER OF(json_array),但在我看来,在 SQLAlchemy 中使用它不太符合人体工程学:

    from sqlalchemy import literal
    
    # self_group forces generation of parenthesis that the syntax requires
    session.query(Story).filter(literal(X).bool_op('MEMBER OF')(Story.section_ids.self_group())).all()
    
    

    【讨论】:

    • 您可以阅读 SQLA here 中的泛型函数。
    • 你确定那是正确的语法吗?它对我不起作用...没有引发错误...只是没有继续下一行...
    • 应该是 str(X)... (在我的情况下 X 是 int 并且只有在转换为字符串时才有效)。谢谢!
    • 我要进行二级搜索,如何指定路径?
    • 是 MySQL 不允许在带有JSON_CONTAINS 的 json 路径中使用通配符。相反,您可以搜索具有所需键值对的对象:func.json_contains(Foo.bar, func.json_object("some_field", "some_value"))
    【解决方案2】:

    对于到达这里但正在使用 PostgreSQL 的人: 您的字段应该是 sqlalchemy.dialects.postgresql.JSONB 类型(而不是 sqlalchemy_utils.JSONType)-

    然后您可以使用与字段关联的Comparator 对象及其contains(和其他)运算符。

    例子:

    Query(Mymodel).filter(MyModel.managers.comparator.contains(["user@gmail.com"]))
    

    (注意,包含的部分必须是JSON片段,而不仅仅是字符串)

    【讨论】:

    • MyModel.managers 在这种情况下是列名(“managers”),而不是一些特殊的关键字。
    猜你喜欢
    • 2022-11-09
    • 1970-01-01
    • 2015-07-22
    • 2021-08-07
    • 2011-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多