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.

Ominus
sumber

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'),
                     )
mobil van
sumber
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))
joash
sumber
1
Pasti __table_args__ = (db.UniqueConstraint('customer_id', 'location_code'),), jangan lupa koma di akhir.
bertdida