2012-04-07 16 views
97

Załóżmy, że mam klasę reprezentującą lokalizacje. Lokalizacje "należą" do klientów. Lokalizacje są identyfikowane przez 10-znakowy kod Unicode. "Kod lokalizacji" powinien być unikalny wśród lokalizacji dla określonego klienta.Unikalne sqlalchemy w wielu kolumnach

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

Więc jeśli mam dwóch klientów, klient "123" i klient "456". Oba mogą mieć lokalizację o nazwie "main", ale żadna z nich nie może mieć dwóch lokalizacji o nazwie main.

mogę sobie z tym poradzić w logice biznesowej, ale chcę, aby upewnić się, że nie ma sposobu, aby łatwo dodać wymóg w SQLAlchemy. Opcja unique = True wydaje się działać tylko wtedy, gdy zostanie zastosowana do określonego pola, a cała tabela będzie miała unikalny kod dla wszystkich lokalizacji.

Odpowiedz

174

Wyciąg z documentation z Column:

wyjątkowy - Kiedy prawda, wskazuje, że kolumna ta zawiera unikalny ograniczenie, lub jeśli Indeks jest prawda, a także wskazuje, że indeks powinien być utworzony z unikalną flagą. Aby określić wiele kolumn w ograniczenie/indeks lub określić jednoznaczną nazwę, użyj UniqueConstraint lub Index konstrukcje wyraźnie.

Jak te należą do tabeli i nie mapowanym klasy, jeden deklaruje te w definicji tabeli, lub w przypadku korzystania deklaratywne jak w __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'), 
        ) 
+0

I wobec tego samego problemu również, ale użycie UniqueConstraint mi nie pomogło. Po spróbowaniu z indeksem ("...") otrzymuję wyjątkowe ograniczenie. Czy istnieje jakieś wytłumaczenie tego zachowania? – swdev

+1

@ swdev: z którego RDBMS korzystasz? – van

+0

Używam PostgreSQL. Czy jest z tym problem? – swdev