yorjo
De acuerdo a la documentación y los comentarios en el sqlalchemy.Column
clase, deberíamos usar la clase sqlalchemy.schema.Index
para especificar un índice que contiene varias columnas.
Sin embargo, el ejemplo muestra cómo hacerlo usando directamente el objeto Tabla de esta manera:
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)
¿Cómo deberíamos hacerlo si usamos la extensión ORM declarativa?
class A(Base):
__tablename__ = 'table_A'
id = Column(Integer, , primary_key=True)
a = Column(String(32))
b = Column(String(32))
Me gustaría un índice en la columna “a” y “b”.
esos son solo Column
objetos, index=True flag funciona normalmente:
class A(Base):
__tablename__ = 'table_A'
id = Column(Integer, primary_key=True)
a = Column(String(32), index=True)
b = Column(String(32), index=True)
si desea un índice compuesto, de nuevo Table
está presente aquí como de costumbre, simplemente no tiene que declararlo, todo funciona igual (asegúrese de estar en 0.6 o 0.7 reciente para que el contenedor Aa declarativo se interprete como un Column
después de completar la declaración de clase):
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)
En 0.7 el Index
puede estar en el Table
argumentos también, que con declarativo es a través de __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"), )
-
Gracias, actualicé a 0.7 y usando el argumentos_tabla funciona bien
– yorjo
12 de julio de 2011 a las 14:57
-
¿Qué sucede si tiene un diccionario para table_args como el que tengo actualmente? argumentos_tabla = {‘mysql_engine’:’InnoDB’}
–Nick Holden
1 de septiembre de 2011 a las 8:39
-
-
Así que supongo que puedo hacer argumentos_tabla = (Índice(‘mi_índice’, “a”, “b”),{‘mysql_engine’:’InnoDB’})
–Nick Holden
19 de octubre de 2011 a las 11:21
-
@RyanChou docs.sqlalchemy.org/en/latest/orm/extensions/declarative/… “Los argumentos de palabras clave se pueden especificar con el formulario anterior especificando el último argumento como un diccionario”
– zzzeek
23 de octubre de 2017 a las 16:18
Mickael
Para completar la respuesta de @zzzeek.
Si desea agregar un índice compuesto con DESC y usar el método declarativo ORM, puede hacer lo siguiente.
Además, estaba luchando con la Índices funcionales documentación de SQLAlchemy, tratando de averiguar cómo sustituir mytable.c.somecol
.
from sqlalchemy import Index Index('someindex', mytable.c.somecol.desc())
Podemos simplemente usar la propiedad del modelo y llamar .desc()
en eso:
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),
)
Si usa Alembic, estoy usando Flask-Migrate, genera algo como:
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 ###
Finalmente, debe tener la siguiente tabla e índices en su base de datos 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)
-
No puedo usar los atributos de clase dentro del
Index
funcion– Rickerp
18 de agosto de 2021 a las 14:52
La pregunta es un poco confusa acerca de si desea múltiples índices o un solo índice en varias columnas (y estaba más confundido antes de editarlo; originalmente pedía deliciosamente “un índice que contiene múltiples índices múltiples”). Pero no importa, supongo, ya que la respuesta de zzzeek aborda ambos casos.
–Mark Amery
5 de enero de 2018 a las 14:12
La pregunta no indica si el índice conjunto debe ser único o no.
– Pynchia
18 de noviembre de 2021 a las 9:11