![](/img/trans.png)
[英]How to create GIN index on text array column in SQLAlchemy (with PostgreSQL and python)
[英]How to create an index on a nested key of a JSON PostgreSQL column in SQLAlchemy?
这是一个棘手的问题,希望有人可以通过使用 SQLAlchemy 在 PostgreSQL 中的 JSON(或 JSONB)列的嵌套键上创建索引的方法来帮助我们所有人(我专门使用 Flask- SQLAlchemy,但我认为这对答案并不重要)。
我已经尝试了下面索引创建的各种排列,并获得了从关键错误到“c”不是属性,再到此表达式不支持运算符“getitem”的所有内容。
任何帮助将不胜感激。
# Example JSON, the nested property is "level2_A"
{
'level1': {
'level2_A': 'test value',
}
}
class TestThing(db.Model):
__tablename__ = 'test_thing'
id = db.Column(db.BigInteger(), primary_key=True)
data = db.Column(JSONB)
__table_args__ = (db.Index('ix_1', TestThing.data['level1']['level2_A']),
db.Index('ix_2', data['level1']['level2_A'].astext),
db.Index('ix_3', "TestThing.c.data['level1']['level2_A'].astext"),
db.Index('ix_4', TestThing.c.data['level1']['level2_A'].astext),
db.Index('ix_5', "test_thing.c.data['level1']['level2_A']"),
)
# db.Index('ix_1', TestThing.data['level1']['level2_A'])
# db.Index('ix_2_t', "test_thing.data['level1']['level2_A']")
# db.Index('ix_3', "TestThing.c.data['level1']['level2_A'].astext")
# db.Index('ix_4', TestThing.c.data['level1']['level2_A'].astext)
# db.Index('ix_5', "test_thing.c.data['level1']['level2_A']")
我发现的解决方案是使用text
来创建功能索引。
这里有两个示例索引,具体取决于您是否要将结果转换为文本:
from sqlalchemy.sql.expression import text
from sqlalchemy.schema import Index
class TestThing(db.Model):
__tablename__ = 'test_thing'
id = db.Column(db.BigInteger(), primary_key=True)
data = db.Column(JSONB)
__table_args__ = (
Index("ix_6", text("(data->'level1'->'level2_A')")),
Index("ix_7", text("(data->'level1'->>'level2_A')")),
)
这导致以下 SQL 来创建索引:
CREATE INDEX ix_6 ON test_thing(((data -> 'level1'::text) -> 'level2_A'::text) jsonb_ops);
CREATE INDEX ix_7 ON test_thing(((data -> 'level1'::text) ->> 'level2_A'::text) text_ops);
class TestThing(db.Model):
__tablename__ = 'test_thing'
id = db.Column(db.BigInteger(), primary_key=True)
data = db.Column(JSONB)
__table_args__ = (
Index("ix_7", "(data->'level1'->>'level2_A')"),
)
理想情况下,这应该在没有 text() 的情况下工作,因为->
返回 json(b) 并且->>
返回文本:
将生成的查询将是
CREATE INDEX ix_7 ON test_thing(((data->'level1')->>'level2_A') text_ops);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.