J'ai une simple classe "Factures" avec un attribut "Nombre" qui doit être affecté par l'application lorsque l'utilisateur enregistre une facture. Il quelques contraintes:Attribut d'incrémentation automatique avec une logique personnalisée dans SQLAlchemy
1) l'application est un (mince) client-serveur un, donc quel que soit attribue le nombre doit regarder les collisions
2) Les factures a un attribut « version », donc je Je ne peux pas utiliser un simple champ auto-incrémenté SGBD
J'essaye de construire ceci en utilisant un type personnalisé qui donnerait un coup de pied dans chaque fois qu'une facture est enregistrée. Chaque fois que process_bind_param est appelé avec une valeur None, il appellera un singleton quelconque pour déterminer le numéro et éviter les collisions. Est-ce une solution décente? Quoi qu'il en soit, je vais avoir un problème .. Voici mon habitude Type:
class AutoIncrement(types.TypeDecorator):
impl = types.Unicode
def copy(self):
return AutoIncrement()
def process_bind_param(self, value, dialect):
if not value:
# Must find next autoincrement value
value = "1" # Test value :)
return value
Mon problème est maintenant droit que lorsque j'enregistre une facture et AutoIncrement ensembles « 1 » comme valeur pour son numéro, l'instance facture ne obtenir mis à jour avec le nouveau nombre .. Est-ce prévu? Ai-je perdu quelque chose? Un grand merci pour votre temps!
(SQLA 0.5.3 sur Python 2.6, en utilisant postgreSQL 8,3)
Edit: Michael Bayer m'a dit que ce comportement est attendu, puisque TypeDecorators ne traitent pas avec des valeurs par défaut.
Aïe ne savais pas que vous pourriez utiliser là appelable, merci! Je vais essayer tout de suite :) – Joril
Dites que votre callable par défaut renvoie le maximum de la colonne dans la base de données plus un. Y a-t-il un moyen d'affirmer qu'il n'y a pas de conditions de concurrence sans compter sur une erreur de la colonne étant unique? –
Dans ce cas, il est préférable d'écrire votre valeur par défaut en tant qu'expression SQL inline. Ceci est couvert en détail dans la documentation SQLAlchemy à http://www.sqlalchemy.org/docs/05/metadata.html#pre-executed-and-inline-sql-expressions –