sqlalchemy unik di beberapa kolom


174

Katakanlah saya memiliki kelas yang mewakili lokasi. Lokasi "milik" pelanggan. Lokasi diidentifikasi oleh kode karakter 10 unicode. "Kode lokasi" harus unik di antara lokasi untuk pelanggan tertentu.

The two below fields in combination should be unique
customer_id = Column(Integer,ForeignKey('customers.customer_id')
location_code = Column(Unicode(10))

Jadi, jika saya memiliki dua pelanggan, pelanggan "123" dan pelanggan "456". Mereka berdua dapat memiliki lokasi yang disebut "utama" tetapi juga tidak dapat memiliki dua lokasi yang disebut utama.

Saya dapat menangani ini dalam logika bisnis tetapi saya ingin memastikan tidak ada cara untuk dengan mudah menambahkan persyaratan dalam sqlalchemy. Pilihan unik = True tampaknya hanya berfungsi ketika diterapkan pada bidang tertentu dan itu akan menyebabkan seluruh tabel hanya memiliki kode unik untuk semua lokasi.

Jawaban:


298

Ekstrak dari dokumentasi dari Column:

unik - Ketika Benar, menunjukkan bahwa kolom ini berisi batasan unik, atau jika indeks juga Benar, menunjukkan bahwa Indeks harus dibuat dengan bendera unik. Untuk menentukan beberapa kolom dalam batasan / indeks atau untuk menentukan nama eksplisit, gunakan UniqueConstraint atau indeks konstruksi secara eksplisit.

Karena ini milik Tabel dan bukan ke Kelas yang dipetakan, seseorang menyatakan mereka dalam definisi tabel, atau jika menggunakan deklaratif seperti pada __table_args__:

# version1: table definition
mytable = Table('mytable', meta,
    # ...
    Column('customer_id', Integer, ForeignKey('customers.customer_id')),
    Column('location_code', Unicode(10)),

    UniqueConstraint('customer_id', 'location_code', name='uix_1')
    )
# or the index, which will ensure uniqueness as well
Index('myindex', mytable.c.customer_id, mytable.c.location_code, unique=True)


# version2: declarative
class Location(Base):
    __tablename__ = 'locations'
    id = Column(Integer, primary_key = True)
    customer_id = Column(Integer, ForeignKey('customers.customer_id'), nullable=False)
    location_code = Column(Unicode(10), nullable=False)
    __table_args__ = (UniqueConstraint('customer_id', 'location_code', name='_customer_location_uc'),
                     )

Saya juga menghadapi masalah yang sama, tetapi menggunakan UniqueConstraint tidak membantu saya. Setelah saya coba dengan Index ('...') maka saya mendapat kendala unik. Apakah ada penjelasan dengan perilaku ini?
swdev

1
@swdev: RDBMS mana yang Anda gunakan?
van

3
Terima kasih, tapi pertanyaan saya adalah: apakah Anda menggunakan SA (dan Labu) untuk membuat skema DB, atau membuatnya secara terpisah?
van

1
Mengapa .c. bekas?
Smiley

1
@Smiley .c.adalah jalan pintas ke.columns.
van

7
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()

class Location(Base):
      __table_args__ = (
        # this can be db.PrimaryKeyConstraint if you want it to be a primary key
        db.UniqueConstraint('customer_id', 'location_code'))
      customer_id = Column(Integer,ForeignKey('customers.customer_id')
      location_code = Column(Unicode(10))

1
Pasti __table_args__ = (db.UniqueConstraint('customer_id', 'location_code'),), jangan lupa koma di akhir.
bertdida
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.