【问题标题】:How to create jsonb index using GIN on SQLAlchemy?如何在 SQLAlchemy 上使用 GIN 创建 jsonb 索引?
【发布时间】:2015-09-02 08:23:42
【问题描述】:

这是当前为 JSONB 创建索引的代码。

Index("mytable_data_idx_id_key", Mytable.data['id'].astext, postgresql_using='gin')

但是我收到了这个错误。

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) data type text has no default operator class for access method "gin"
HINT:  You must specify an operator class for the index or define a default operator class for the data type.
 [SQL: "CREATE INDEX event_data_idx_id_key ON event USING gin ((data ->> 'id'))"]

有没有办法在 SQLAlchemy 上创建索引?

【问题讨论】:

    标签: python postgresql indexing sqlalchemy


    【解决方案1】:

    我不知道自上一个接受的答案以来 sqlalchemy 是否发生了变化,但在我工作的代码库中,这是通过以下方式完成的:

        __table_args__ = (
            db.Index(
                "index_TABLENAME_on_COLUMN_gin", 
                "COLUMN", 
                postgresql_using="gin",
            ),
        )
    

    这将在 Postgresql 中创建预期的 GIN 索引。

    【讨论】:

      【解决方案2】:

      http://docs.sqlalchemy.org/en/latest/dialects/postgresql.html#operator-classes 上的 PostgreSQL 特定 SQLAlchemy 文档提到了一个 postgresql_ops 字典,以提供 PostgreSQL 使用的“操作符类”,并提供此示例说明其用法:

      Index('my_index', my_table.c.id, my_table.c.data,
                              postgresql_ops={
                                  'data': 'text_pattern_ops',
                                  'id': 'int4_ops'
                              })
      

      从实验来看,如果要为表达式索引指定“运算符类”,似乎需要使用text() 索引描述。所以,

      db.Index(
          'ix_sample',
          sqlalchemy.text("(jsoncol->'values') jsonb_path_ops"),
          postgresql_using="gin")
      

      ...in __table_args__ 对于 ORM 模型,在包含字符串数组的 jsonb 字段上指定 GIN 索引,并允许高效查找,即匹配 JSON 数组字段中的任何字符串看起来像这样:

      {
        "values": ["first", "second", "third"],
        "other": "fields",
        "go": "here"
      }
      

      在 PostgreSQL 中使用 @> 运算符进行查询看起来像这样:

      import sqlalchemy
      from sqlalchemy.dialects import postgresql
      
      query = session.query(MyModel).filter(
          sqlalchemy.type_coerce(MyModel.jsoncol['values'], postgresql.JSONB)
          .contains(sqlalchemy.type_coerce("second", postgresql.JSONB)))
      results = query.all()
      

      【讨论】:

      • 我试过了,但我得到了错误。 sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) operator class "text_pattern_ops" does not accept data type jsonb
      猜你喜欢
      • 1970-01-01
      • 2019-11-11
      • 2019-01-29
      • 2020-06-10
      • 1970-01-01
      • 1970-01-01
      • 2016-09-20
      • 1970-01-01
      • 2023-03-19
      相关资源
      最近更新 更多