Selon la documentation et les commentaires dans le sqlalchemy.Column
classe, nous devrions utiliser la classe sqlalchemy.schema.Index
pour spécifier un index contenant plusieurs colonnes.
Cependant, l'exemple montre comment le faire en utilisant directement l'objet Table comme ceci:
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)
Comment devrions-nous le faire si nous utilisons l'extension déclarative ORM?
class A(Base):
__table= 'table_A'
id = Column(Integer, , primary_key=True)
a = Column(String(32))
b = Column(String(32))
Je voudrais un index sur la colonne "a" et "b".
ce ne sont que des objets Column
, index = True flag fonctionne normalement:
class A(Base):
__table= 'table_A'
id = Column(Integer, primary_key=True)
a = Column(String(32), index=True)
b = Column(String(32), index=True)
si vous souhaitez un index composite, encore une fois Table
est présent ici comme d'habitude, vous n'avez tout simplement pas à le déclarer, tout fonctionne de la même manière (assurez-vous que vous êtes sur la version 0.6 ou 0.7 récente pour la déclaration Aa wrapper à interpréter comme Column
une fois la déclaration de classe terminée):
class A(Base):
__table= 'table_A'
id = Column(Integer, primary_key=True)
a = Column(String(32))
b = Column(String(32))
Index('my_index', A.a, A.b)
Dans 0.7, le Index
peut aussi être dans les arguments Table
, qui avec déclaratif se fait via __table_args__
:
class A(Base):
__table= 'table_A'
id = Column(Integer, primary_key=True)
a = Column(String(32))
b = Column(String(32))
__table_args__ = (Index('my_index', "a", "b"), )
Pour compléter @ zzzeek réponse .
Si vous souhaitez ajouter un index composite avec DESC et utiliser la méthode déclarative ORM, vous pouvez procéder comme suit.
De plus, je me débattais avec la documentation Functional Indexes de SQSAlchemy, essayant de trouver un moyen de remplacer mytable.c.somecol
.
from sqlalchemy import Index Index('someindex', mytable.c.somecol.desc())
Nous pouvons simplement utiliser la propriété model et appeler .desc()
dessus:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class GpsReport(db.Model):
__table= '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),
)
Si vous utilisez Alembic, j'utilise Flask-Migrate, cela génère quelque chose comme:
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 ###
Enfin, vous devriez avoir le tableau et les index suivants dans votre base de données 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)