Sqlalchemy के घोषणात्मक ORM विस्तार का उपयोग करते समय कई कॉलम सूचकांक


94

प्रलेखन और sqlalchemy.Columnकक्षा में टिप्पणियों के अनुसार , हमें sqlalchemy.schema.Indexएक सूचकांक निर्दिष्ट करने के लिए कक्षा का उपयोग करना चाहिए जिसमें कई कॉलम होते हैं।

हालाँकि, उदाहरण दिखाता है कि टेबल ऑब्जेक्ट को सीधे इस तरह से कैसे करना है:

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))

मैं कॉलम "a" और "b" पर एक सूचकांक चाहूंगा।


1
यह सवाल थोड़ा अस्पष्ट है कि क्या आप कई कॉलमों पर एक से अधिक इंडेक्स या एक इंडेक्स चाहते हैं (और मैंने इसे संपादित करने से पहले और अधिक भ्रमित किया था - मूल रूप से इसे "एक इंडेक्स जिसमें कई मल्टीपल इंडेक्स होते हैं" के लिए पूछा गया था )। लेकिन कोई बात नहीं, मुझे लगता है, क्योंकि zzzeek का जवाब दोनों मामलों को संबोधित करता है।
मार्क अमेरी

जवाबों:


137

वे सिर्फ Columnऑब्जेक्ट हैं, इंडेक्स = ट्रू फ्लैग सामान्य रूप से काम करता है:

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 पर घोषित एए रैपर के रूप में व्याख्या करने के लिए हैं 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"), )

1
धन्यवाद, मैं 0.7 के लिए अद्यतन और का उपयोग कर table_args ठीक काम करता है
yorjo

5
यदि मेरे पास वर्तमान में टेबल_रग्स जैसा शब्दकोश है तो क्या होता है? table_args = {'mysql_engine': 'InnoDB'}
निक होल्डन


6
तो मुझे लगता है मैं क्या कर सकते हैं table_args = (सूचकांक ( 'my_index', "एक", "ख"), { 'mysql_engine': 'InnoDB'})
निक होल्डन

1
@RyanChou docs.sqlalchemy.org/en/latest/orm/extensions/declarative/… "अंतिम तर्क को एक शब्दकोष के रूप में निर्दिष्ट करके उपरोक्त रूप के साथ निर्दिष्ट किया जा सकता है"
zzzeek

12

@ Zzzeek का जवाब पूरा करने के लिए ।

यदि आप DESC के साथ एक समग्र सूचकांक जोड़ना चाहते हैं और ORM घोषणात्मक विधि का उपयोग कर सकते हैं जो आप निम्नानुसार कर सकते हैं।

इसके अलावा, मैं SQSAlchemy के फंक्शनल इंडेक्स डॉक्यूमेंटेशन के साथ संघर्ष कर रहा था , यह पता लगाने की कोशिश कर रहा था कि कैसे विकल्प का उपयोग किया जाए mytable.c.somecol

from sqlalchemy import Index

Index('someindex', mytable.c.somecol.desc())

हम केवल मॉडल संपत्ति का उपयोग कर सकते हैं और .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),
    )

यदि आप अलेम्बिक का उपयोग करते हैं, तो मैं फ्लास्क-माइग्रेट का उपयोग कर रहा हूं, यह कुछ ऐसा उत्पन्न करता है:

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 ###

अंत में आपको अपने पोस्टग्रेक्यूएल डेटाबेस में निम्न तालिका और अनुक्रमित होना चाहिए:

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)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.