问题
A quick SQLAlchemy question...
I have a class "Document" with attributes "Number" and "Date". I need to ensure that there's no duplicated number for the same year, is there a way to have a UniqueConstraint on "Number + year(Date)"? Should I use a unique Index instead? How would I declare the functional part?
(SQLAlchemy 0.5.5, PostgreSQL 8.3.4)
Thanks in advance!
回答1:
You should use a functional unique index to apply this constraint. Unfortunately the database generic database independent schema definition machinery in SQLAlchemy doesn't abstract functional indexes yet. You'll have to use the DDL construct to register custom schema definition clauses. If you are using the declarative approach to declaring your schema add the following after your class definition:
DDL(
"CREATE UNIQUE INDEX doc_year_num_uniq ON %(fullname)s "
"(EXTRACT(YEAR FROM date), number)"
).execute_at('after-create', Document.__table__)
This method works very nicely but throws a SADeprecation warning in v0.7 The syntax that I've used successfully:
from sqlalchemy import event
event.listen(ModelObject.__table__,
'after_create',
DDL("CREATE UNIQUE INDEX term_year ON %(fullname)s "
"(EXTRACT(YEAR FROM start_date), term)",
on = 'postgresql'
)
)
回答2:
I'm pretty sure that unique constraints can only be applied on columns that already have data in them, and not on runtime-calculated expressions. Hence, you would need to create an extra column which contains the year
part of your date
, over which you could create a unique constraint together with number
. To best use this approach, maybe you should store your date
split up in three separate columns containing the day, month and year part. This could be done using default constraints in the table definition.
来源:https://stackoverflow.com/questions/1510018/compound-uniqueconstraint-with-a-function