Zgodnie z dokumentacją i komentarzami w sqlalchemy.Column
klasie powinniśmy użyć klasy sqlalchemy.schema.Index
do określenia indeksu zawierającego wiele kolumn.
Jednak przykład pokazuje, jak to zrobić, używając bezpośrednio obiektu Table w następujący sposób:
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)
Jak mamy to zrobić, jeśli używamy deklaratywnego rozszerzenia ORM?
class A(Base):
__tablename__ = 'table_A'
id = Column(Integer, , primary_key=True)
a = Column(String(32))
b = Column(String(32))
Chciałbym mieć indeks w kolumnach „a” i „b”.
Odpowiedzi:
to tylko
Column
obiekty, index = True flaga działa normalnie:class A(Base): __tablename__ = 'table_A' id = Column(Integer, primary_key=True) a = Column(String(32), index=True) b = Column(String(32), index=True)
jeśli chcesz mieć indeks złożony, ponownie
Table
jest obecny tutaj, jak zwykle, po prostu nie musisz go deklarować, wszystko działa tak samo (upewnij się, że jesteś na ostatnim 0,6 lub 0,7, aby deklaratywne opakowanie Aa było interpretowane jakoColumn
po zakończeniu deklaracji klasy):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)
W wersji 0.7
Index
może być również wTable
argumentach, co w przypadku deklaratywnego odbywa się poprzez__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"), )
źródło
Aby zakończyć @ zzzeek za odpowiedź .
Jeśli chcesz dodać indeks złożony z DESC i użyć deklaratywnej metody ORM, możesz wykonać następujące czynności.
Co więcej, zmagałem się z dokumentacją indeksów funkcjonalnych SQSAlchemy, próbując wymyślić, jak zastąpić
mytable.c.somecol
.Możemy po prostu użyć właściwości model i wywołać
.desc()
ją: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), )
Jeśli używasz Alembic, ja używam Flask-Migrate, generuje coś takiego:
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 ###
Na koniec powinieneś mieć następującą tabelę i indeksy w swojej bazie danych 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)
źródło