SQLAlchemy/Alembic необработанный SQL для добавления индекса

Я хотел бы использовать следующий необработанный SQL для создания индекса в PostgreSQL:

CREATE INDEX ix_action_date ON events_map ((action ->> 'action'), date, map_id);

Я попытался поместить эту строку в часть __table_args__ класса модели, но не смог. Затем я просто решил это, используя необработанный SQL в миграции Alembic.

conn = op.get_bind()
conn.execute(text("CREATE INDEX ..."))

и просто используя фиктивный индекс в __table_args__, например:

Index('ix_action_date')

Моя единственная проблема заключается в том, что Alembic не принимает фиктивный индекс с тем же именем, и каждый раз, когда я запускаю revision --autogenerate, он сообщает мне следующее:

SAWarning: Skipped unsupported reflection of expression-based index ix_action_date
  % idx_name)

а затем добавляет автоматически сгенерированный индекс в файл миграции:

op.create_index('ix_action_date', 'events_map', [], unique=False)

Мой вопрос:

  1. Как я могу записать необработанный SQL в индекс __table_args__?

  2. Как я могу действительно заставить мою концепцию фиктивного индекса работать? Я имею в виду индекс, который сравнивается только по имени?


person hyperknot    schedule 08.07.2018    source источник
comment
Не могли бы вы добавить немного больше подробностей о том, что я пытался поместить эту строку в часть __table_args__ класса модели, но не смог? Это похоже на проблему XY.   -  person Ilja Everilä    schedule 09.07.2018
comment
Я использую SQLAlchemy ORM. Каждая модель указана в классе. Переменная table_args в этом классе задает настраиваемые свойства таблицы, например индексы. Я хотел бы объявить свой индекс в table_args.   -  person hyperknot    schedule 09.07.2018
comment
Имелось в виду больше похожее на редактирование вашего вопроса, чтобы включить ваше декларативное определение с неудачной попыткой и тем, как она терпит неудачу. Если вы создаете индекс в своей миграции вручную, используя необработанный SQL, вам даже не обязательно нужен Index в аргументах вашей таблицы, не говоря уже о фиктивном.   -  person Ilja Everilä    schedule 09.07.2018
comment
Вы правы, кажется, что если я удалю индекс из аргументов таблицы, это сработает, мне просто нужно жить с: Skipped unsupported reflection of expression-based index для каждого --autogenerate.   -  person hyperknot    schedule 09.07.2018
comment
Тем не менее, что касается 1-го комментария, SQLA поддерживает выражения в индексах, по крайней мере, для диалекта Postgresql, поэтому создание определения Index для выражения столбца json (b) и остальных должно было быть возможным.   -  person Ilja Everilä    schedule 09.07.2018
comment
Да, мне все еще интересно это выяснить. Мои неудачные попытки были быстрыми и бессмысленными, если кто-то может поделиться информацией, это будет ценная информация.   -  person hyperknot    schedule 09.07.2018


Ответы (1)


Как я могу записать необработанный SQL в индекс __table_args__?

Чтобы указать индексы формулы, вы должны предоставить текстовый элемент для выражения

пример:

class EventsMap(Base):
    __tablename__ = 'events_map'
    __table_args__ = (Index('ix_action_date', text("(action->>'action'), date, map_id")),)
    map_id = Column(Integer, primary_key=True)
    date = Column(DateTime)
    action = Column(JSONB)

Как я могу действительно заставить мою концепцию фиктивного индекса работать? Я имею в виду индекс, который сравнивается только по имени?

Кажется ненужным заставить вашу концепцию фиктивного индекса работать. Либо укажите полное выражение индекса в __table_args__, как показано выше, либо полностью исключите его из модели и делегируйте создание индекса в качестве миграции базы данных, обрабатываемой sqlalchemy.

person Haleemur Ali    schedule 26.05.2019