2012-04-07 22 views
97

Digamos que tengo una clase que representa ubicaciones. Las ubicaciones "pertenecen" a los clientes. Las ubicaciones se identifican mediante un código de 10 caracteres Unicode. El "código de ubicación" debe ser único entre las ubicaciones para un cliente específico.sqlalchemy único en múltiples columnas

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

Así que si tengo dos clientes, el cliente "123" y el cliente "456". Ambos pueden tener una ubicación llamada "principal", pero ninguno podría tener dos ubicaciones llamadas main.

Puedo manejar esto en la lógica comercial, pero quiero asegurarme de que no hay forma de agregar fácilmente el requisito en sqlalchemy. La opción unique = True parece funcionar solo cuando se aplica a un campo específico y causaría que toda la tabla solo tenga un código único para todas las ubicaciones.

Respuesta

174

Extracto del documentation del Column:

única - Cuando verdadera, indica que esta columna contiene una única restricción, o si índice es verdad también, indica que el Índice de debe ser creado con la bandera única. Para especificar varias columnas en la restricción/índice o para especificar un nombre explícito, utilice las construcciones UniqueConstraint o Index explícitamente.

A medida que estos pertenecen a una tabla y no a una clase asignada, se declara los de la definición de la tabla, o si se utiliza declarativa como en el __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

que se enfrentan al mismo problema, pero usar UniqueConstraint no me ayudó. Después de probar con Index ('...'), obtengo una restricción única. ¿Hay alguna explicación con este comportamiento? – swdev

+1

@swdev: ¿qué RDBMS usas? – van

+0

Estoy usando PostgreSQL. ¿Hay algún problema con esto? – swdev

Cuestiones relacionadas