2012-04-07 2 views
97

Sagen wir, dass ich eine Klasse habe, die Standorte darstellt. Standorte gehören zu den Kunden. Standorte werden durch einen Unicode-Code mit 10 Zeichen identifiziert. Der "Standortcode" sollte unter den Standorten für einen bestimmten Kunden eindeutig sein.sqlalchemy einzigartig über mehrere Spalten

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

Also, wenn ich zwei Kunden habe, Kunde "123" und Kunde "456". Beide können einen Ort namens "main" haben, aber keiner könnte zwei Orte namens main haben.

Ich kann dies in der Geschäftslogik behandeln, aber ich möchte sicherstellen, dass es keine Möglichkeit gibt, die Anforderung in sqlalchemy einfach hinzuzufügen. Die Option "unique = True" scheint nur dann zu funktionieren, wenn sie auf ein bestimmtes Feld angewendet wird. Dadurch würde die gesamte Tabelle nur einen eindeutigen Code für alle Standorte enthalten.

Antwort

174

Auszug aus den documentation der Column:

einzigartigen - Wenn wahr, gibt an, daß diese Spalte einen eindeutig constraint enthält oder wenn Index auch Wahr ist, gibt an, dass der Index sollte mit der einzigartigen Flagge erstellt werden. Um mehrere Spalten in Constraint/Index anzugeben oder einen expliziten Namen anzugeben, verwenden Sie explizit die UniqueConstraint oder Index Konstrukte.

Da diese gehören zu einer Tabelle und nicht auf einem zugeordneten Klasse, eine in der Tabelle Definition erklärt, oder, wie in der __table_args__ deklarative bei Verwendung von:

# 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

ich auch vor dem gleichen Problem, aber mit UniqueConstraint hat mir nicht geholfen. Nachdem ich mit Index ('...') versucht habe, bekomme ich eine eindeutige Einschränkung. Gibt es eine Erklärung für dieses Verhalten? – swdev

+1

@swdev: Welches RDBMS verwenden Sie? – van

+0

Ich benutze PostgreSQL. Gibt es ein Problem damit? – swdev