sqlalchemy унікальна у кількох стовпцях


174

Скажімо, у мене є клас, який представляє місця. Місцеположення "належить" клієнтам. Місцеположення ідентифікується кодом символу 10 символів. "Код локації" повинен бути унікальним серед локацій для конкретного замовника.

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

Тож якщо у мене є два клієнти, клієнт "123" та клієнт "456". Обидва вони можуть мати місце, яке називається "головним", але ні два не можуть мати два місця, що називаються головними.

Я можу впоратися з цим у бізнес-логіці, але хочу переконатися, що немає можливості легко додати вимогу в sqlalchemy. Здається, що унікальний варіант = True працює лише тоді, коли він застосовується до певного поля, і це призведе до того, що вся таблиця має унікальний код для всіх локацій.

Відповіді:


298

Виписка з документації з Column:

унікальний - коли True, вказує, що цей стовпець містить унікальне обмеження, або якщо індекс також є True, вказує на те, що індекс слід створювати за допомогою унікального прапора. Щоб вказати кілька стовпців у обмеженні / індексі або вказати явне ім'я, використовуйте конструкції UniqueConstraint або Index явно.

Оскільки вони належать до таблиці, а не до відображеного у класі класу, то вони оголошують ті, які є у визначенні таблиці, або якщо вони використовують декларативний, як у __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'),
                     )

Я зіткнувся з тією ж проблемою, але використання UniqueConstraint не допомогло мені. Після того як я спробую з Index ('...'), тоді я отримую унікальне обмеження. Чи є пояснення з такою поведінкою?
swdev

1
@swdev: якими RDBMS ви користуєтесь?
ван

3
Дякую, але моє запитання було: ви використовували SA (і колбу) для створення схеми БД, чи створювали її окремо?
ван

1
Чому дорівнює .c використаний?
Смайлик

1
@Smiley .c.є ярликом.columns.
ван

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
Має бути __table_args__ = (db.UniqueConstraint('customer_id', 'location_code'),), не забудьте коску наприкінці.
bertdida
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.