簡體   English   中英

如何在 SQLAlchemy 中的 JSON PostgreSQL 列的嵌套鍵上創建索引?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM