2009-10-02 5 views
3

Une question SQLAlchemy rapide ...composé UniqueConstraint avec une fonction

J'ai une classe "Document" avec des attributs "Number" et "Date". Je dois m'assurer qu'il n'y a pas de numéro dupliqué pour la même année, y at-il un moyen d'avoir une contrainte unique sur "Numéro + année (date)"? Dois-je utiliser un index unique à la place? Comment pourrais-je déclarer la partie fonctionnelle?

(SQLAlchemy 0.5.5, PostgreSQL 8.3.4)

Merci à l'avance!

Répondre

3

Vous devez utiliser un index unique fonctionnel pour appliquer cette contrainte. Malheureusement, la base de données générique machines de définition de schéma indépendant dans SQLAlchemy ne permet pas encore d'abstraire les index fonctionnels. Vous devrez utiliser la construction DDL pour enregistrer les clauses de définition de schéma personnalisées. Si vous utilisez l'approche déclarative pour déclarer votre schéma ajouter ce qui suit après votre définition de classe:

DDL(
    "CREATE UNIQUE INDEX doc_year_num_uniq ON %(fullname)s " 
    "(EXTRACT(YEAR FROM date), number)" 
).execute_at('after-create', Document.__table__) 

Cette méthode fonctionne très bien, mais jette un avertissement SADeprecation dans v0.7 La syntaxe que je l'ai utilisé avec succès:

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' 
      ) 
     ) 
+0

Cela fonctionne bien, merci beaucoup :) – Joril

+0

Note: le '% (fullname) s' est rempli dans SQLAlchemy à partir des informations dans le champ de la table, ici' ModelObject .__ table__'. –

0

Je suis certain que les contraintes uniques ne peuvent être appliquées que sur les colonnes qui contiennent déjà des données, et non sur les expressions calculées à l'exécution. Par conséquent, vous devez créer une colonne supplémentaire contenant la partie year de votre date, sur laquelle vous pouvez créer une contrainte unique avec number. Pour utiliser au mieux cette approche, vous devriez peut-être stocker votre date divisé en trois colonnes séparées contenant le jour, le mois et l'année. Cela pourrait être fait en utilisant des contraintes par défaut dans la définition de la table.

+0

Je vois .. Donc peut-être que je devrais aller pour un index unique au lieu d'une contrainte .. Je vais mettre à jour la question, merci pour votre contribution! – Joril

Questions connexes