sqlalchemy duy nhất trên nhiều cột


174

Hãy nói rằng tôi có một lớp đại diện cho các địa điểm. Địa điểm "thuộc về" khách hàng. Vị trí được xác định bởi mã 10 ký tự unicode. "Mã vị trí" phải là duy nhất trong số các vị trí cho một khách hàng cụ thể.

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

Vì vậy, nếu tôi có hai khách hàng, khách hàng "123" và khách hàng "456". Cả hai đều có thể có một vị trí gọi là "chính" nhưng không thể có hai vị trí được gọi là chính.

Tôi có thể xử lý điều này trong logic kinh doanh nhưng tôi muốn chắc chắn rằng không có cách nào để dễ dàng thêm yêu cầu trong sqlalchemy. Tùy chọn unique = True dường như chỉ hoạt động khi được áp dụng cho một trường cụ thể và nó sẽ khiến toàn bộ bảng chỉ có một mã duy nhất cho tất cả các vị trí.

Câu trả lời:


298

Trích xuất từ ​​các tài liệu của Column:

unique - Khi True, chỉ ra rằng cột này chứa một ràng buộc duy nhất hoặc nếu chỉ mục là True, chỉ ra rằng Index phải được tạo bằng cờ duy nhất. Để chỉ định nhiều cột trong ràng buộc / chỉ mục hoặc để chỉ định một tên rõ ràng, hãy sử dụng các cấu trúc UniqueConstraint hoặc Index một cách rõ ràng.

Vì các bảng này thuộc về Bảng chứ không thuộc về Lớp được ánh xạ, nên người ta khai báo những người trong định nghĩa bảng hoặc nếu sử dụng khai báo như trong __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'),
                     )

Tôi cũng gặp phải vấn đề tương tự, nhưng sử dụng UniqueConstraint đã không giúp tôi. Sau khi tôi thử với Index ('...') thì tôi nhận được một ràng buộc duy nhất. Có bất kỳ lời giải thích với hành vi này?
swdev

1
@swdev: bạn sử dụng RDBMS nào?
xe van

3
Cảm ơn, nhưng câu hỏi của tôi là: bạn đã sử dụng SA (và Flask) để tạo lược đồ DB hay đã tạo riêng nó?
van

1
Tại sao là .c. đã sử dụng?
Smiley

1
@Smiley .c.là một lối tắt đến.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))

1
Phải __table_args__ = (db.UniqueConstraint('customer_id', 'location_code'),), đừng quên dấu phẩy ở cuối.
bertdida
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.