Согласно документации и комментариям в sqlalchemy.Column
классе, мы должны использовать класс sqlalchemy.schema.Index
для указания индекса, который содержит несколько столбцов.
Однако в примере показано, как это сделать, напрямую используя объект Table следующим образом:
meta = MetaData()
mytable = Table('mytable', meta,
# an indexed column, with index "ix_mytable_col1"
Column('col1', Integer, index=True),
# a uniquely indexed column with index "ix_mytable_col2"
Column('col2', Integer, index=True, unique=True),
Column('col3', Integer),
Column('col4', Integer),
Column('col5', Integer),
Column('col6', Integer),
)
# place an index on col3, col4
Index('idx_col34', mytable.c.col3, mytable.c.col4)
Как это сделать, если мы используем декларативное расширение ORM?
class A(Base):
__tablename__ = 'table_A'
id = Column(Integer, , primary_key=True)
a = Column(String(32))
b = Column(String(32))
Мне нужен указатель столбцов «а» и «б».
Ответы:
это просто
Column
объекты, флаг index = True работает нормально:class A(Base): __tablename__ = 'table_A' id = Column(Integer, primary_key=True) a = Column(String(32), index=True) b = Column(String(32), index=True)
Если вам нужен составной индекс, он снова
Table
присутствует здесь, как обычно, вам просто не нужно его объявлять, все работает одинаково (убедитесь, что вы используете последние версии 0.6 или 0.7, чтобы декларативная оболочка Aa интерпретировалась какColumn
после завершения объявления класса):class A(Base): __tablename__ = 'table_A' id = Column(Integer, primary_key=True) a = Column(String(32)) b = Column(String(32)) Index('my_index', A.a, A.b)
В версии 0.7 аргументы также
Index
могут быть включены вTable
аргументы, что с декларативным использованием__table_args__
:class A(Base): __tablename__ = 'table_A' id = Column(Integer, primary_key=True) a = Column(String(32)) b = Column(String(32)) __table_args__ = (Index('my_index', "a", "b"), )
источник
Чтобы завершить ответ @zzzeek .
Если вы хотите добавить составной индекс с помощью DESC и использовать декларативный метод ORM, вы можете сделать следующее.
Кроме того, я боролся с документацией по функциональным индексам SQSAlchemy, пытаясь выяснить, как заменить
mytable.c.somecol
.Мы можем просто использовать свойство модели и вызвать
.desc()
его:from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() class GpsReport(db.Model): __tablename__ = 'gps_report' id = db.Column(db.Integer, db.Sequence('gps_report_id_seq'), nullable=False, autoincrement=True, server_default=db.text("nextval('gps_report_id_seq'::regclass)")) timestamp = db.Column(db.DateTime, nullable=False, primary_key=True) device_id = db.Column(db.Integer, db.ForeignKey('device.id'), primary_key=True, autoincrement=False) device = db.relationship("Device", back_populates="gps_reports") # Indexes __table_args__ = ( db.Index('gps_report_timestamp_device_id_idx', timestamp.desc(), device_id), )
Если вы используете Alembic, я использую Flask-Migrate, он генерирует что-то вроде:
from alembic import op import sqlalchemy as sa # Added manually this import from sqlalchemy.schema import Sequence, CreateSequence def upgrade(): # ### commands auto generated by Alembic - please adjust! ### # Manually added the Sequence creation op.execute(CreateSequence(Sequence('gps_report_id_seq'))) op.create_table('gps_report', sa.Column('id', sa.Integer(), server_default=sa.text("nextval('gps_report_id_seq'::regclass)"), nullable=False), sa.Column('timestamp', sa.DateTime(), nullable=False)) sa.Column('device_id', sa.Integer(), autoincrement=False, nullable=False), op.create_index('gps_report_timestamp_device_id_idx', 'gps_report', [sa.text('timestamp DESC'), 'device_id'], unique=False) def downgrade(): # ### commands auto generated by Alembic - please adjust! ### op.drop_index('gps_report_timestamp_device_id_idx', table_name='gps_report') op.drop_table('gps_report') # Manually added the Sequence removal op.execute(sa.schema.DropSequence(sa.Sequence('gps_report_id_seq'))) # ### end Alembic commands ###
Наконец, у вас должна быть следующая таблица и индексы в базе данных PostgreSQL:
psql> \d gps_report; Table "public.gps_report" Column | Type | Collation | Nullable | Default -----------------+-----------------------------+-----------+----------+---------------------------------------- id | integer | | not null | nextval('gps_report_id_seq'::regclass) timestamp | timestamp without time zone | | not null | device_id | integer | | not null | Indexes: "gps_report_pkey" PRIMARY KEY, btree ("timestamp", device_id) "gps_report_timestamp_device_id_idx" btree ("timestamp" DESC, device_id) Foreign-key constraints: "gps_report_device_id_fkey" FOREIGN KEY (device_id) REFERENCES device(id)
источник