[英]How to create jsonb index using GIN on SQLAlchemy?
Here's current code creating index for JSONB.这是为 JSONB 创建索引的当前代码。
Index("mytable_data_idx_id_key", Mytable.data['id'].astext, postgresql_using='gin')
But I got this error.但我收到了这个错误。
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'))"]
Is there any way to create index on SQLAlchemy?有没有办法在 SQLAlchemy 上创建索引?
The PostgreSQL specific SQLAlchemy docs at http://docs.sqlalchemy.org/en/latest/dialects/postgresql.html#operator-classes mention a postgresql_ops
dictionary to provide the "operator class" used by PostgreSQL, and provide this example illustrating its use: 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'
})
From experimenting, it seems that you need to use a text()
index description if you want to specify the "operator class" for an expression index.从实验来看,如果要为表达式索引指定“运算符类”,似乎需要使用text()
索引描述。 So,所以,
db.Index(
'ix_sample',
sqlalchemy.text("(jsoncol->'values') jsonb_path_ops"),
postgresql_using="gin")
...in __table_args__
for an ORM model specifies a GIN index on a jsonb
field that contains an array of strings, and that allows for efficient lookups, ie matching on any of the strings in the JSON array field that looks like this: ...在__table_args__
用于ORM模型指定上的一个索引GIN jsonb
字段包含一个字符串数组,并且,可实现有效的查找,即匹配于任何以JSON阵列字段中的字符串的,看起来像这样:
{
"values": ["first", "second", "third"],
"other": "fields",
"go": "here"
}
Querying using the @>
operator in PostgreSQL would look something like this:在 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()
I don't know if things have changed in sqlalchemy since the previous accepted answer, but in the code base I work in, this was done with the following:我不知道自上一个接受的答案以来 sqlalchemy 中的情况是否发生了变化,但在我工作的代码库中,这是通过以下方式完成的:
__table_args__ = (
db.Index(
"index_TABLENAME_on_COLUMN_gin",
"COLUMN",
postgresql_using="gin",
),
)
This will create the expected GIN index in Postgresql.这将在 Postgresql 中创建预期的 GIN 索引。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.