2010-07-31 6 views
3

Dans une application Django je dois créer un numéro d'ordre qui ressemble à: yyyymmddnnnn où aaaa = année, mm = mois, dd = jour et nnnn est un nombre compris entre 1 et 9999.Django, l'accès à la séquence de PostgreSQL

J'ai pensé que je pourrais utiliser une séquence PostgreSQL puisque les nombres générés sont atomiques, donc je peux être sûr que lorsque le processus aura un nombre ce nombre est unique.

Je créé une séquence PostgreSQL:

CREATE SEQUENCE order_number_seq 
INCREMENT 1 
MINVALUE 1 
MAXVALUE 9999 
START 1 
CACHE 1 
CYCLE; 

Cette séquence est accessible en tant que tables ayant une ligne. Donc, dans le fichier checkout.py, j'ai créé un modèle Django pour accéder à cette séquence.

class OrderNumberSeq(models.Model): 
    """ 
    This class maps to OrderNumberSeq which is a PostgreSQL sequence. 
    This sequence runs from 1 to 9999 after which it restarts (cycles) at 1. 
    A sequence is basically a special single row table. 
    """ 
    sequence_name = models.CharField(max_length=128, primary_key=True) 
    last_value = models.IntegerField() 
    increment_by = models.IntegerField() 
    max_value = models.IntegerField() 
    min_value = models.IntegerField() 
    cache_value = models.IntegerField() 
    log_cnt = models.IntegerField() 
    is_cycled = models.BooleanField() 
    is_called = models.BooleanField() 

    class Meta: 
     db_table = u'order_number_seq' 

J'ai défini le nom de séquence comme clé primaire car Django insiste pour avoir une clé primaire dans une table.

Le I a créé un get_order_number.py de fichier avec le contenu:

def get_new_order_number(): 
    order_number = OrderNumberSeq.objects.raw("select sequence_name, nextval('order_number_seq') from order_number_seq")[0] 

    today = datetime.date.today() 
    year = u'%4s' % today.year 
    month = u'%02i' % today.month 
    day = u'%02i' % today.day 

    new_number = u'%04i' % order_number.nextval 
    return year+month+day+new_number 

maintenant quand je l'appelle 'get_new_order_number()' depuis le shell django il se comporte comme prévu.

>>> checkout.order_number.get_new_order_number() 
u'201007310047' 
>>> checkout.order_number.get_new_order_number() 
u'201007310048' 
>>> checkout.order_number.get_new_order_number() 
u'201007310049' 

Vous voyez les nombres s'incrémenter de manière agréable d'un cran chaque fois que la fonction est appelée. Vous pouvez démarrer plusieurs sessions django interactives et les nombres s'incrémentent sans aucun chiffre identique apparaissant dans les différentes sessions.

Maintenant, j'essaie d'utiliser appeler cette fonction d'une vue comme suit:

import get_order_number 

order_number = get_order_number.get_new_order_number() 

et il me donne un numéro. Cependant la prochaine fois que j'accède à la vue, il incrémente le nombre par 2. Je n'ai aucune idée où le problème est.

+0

Je pense que nous devons voir plus de votre code de vue. – KillianDS

+0

Fondamentalement, il n'y a pas beaucoup plus dans le code de la vue. Mais j'ai changé d'avis sur la façon de générer des numéros de commande de toute façon. J'avais besoin de générer des numéros de commande uniques pour pouvoir suivre les commandes si nécessaire. Et la façon dont j'ai essayé, a un sérieux inconvénient. Je dois réinitialiser le compteur tous les jours à minuit exactement. De toute façon, vous tous, merci d'avoir répondu. – Henri

+0

Il est apparu que l'erreur était dans une autre partie de l'application, donc le problème est résolu. Quelque part, j'ai lu quelque chose sur la génération de numéros de commande: http://stackoverflow.com/questions/1179439/best-way-to-generate-order-numbers-for-an-online-store et voici quelques conseils très utiles. – Henri

Répondre

3

La meilleure solution que je peux trouver est: ne vous inquiétez pas si vos numéros de commande sont clairsemés. Peu importe si un numéro de commande est manquant: il n'y a aucun moyen de s'assurer que les numéros de commande sont contigus et qu'ils ne seront pas soumis à une condition de concurrence à un moment donné.

Votre plus gros problème sera probablement de convaincre les personnes aux cheveux pointus que les numéros de commande «manquants» ne posent aucun problème.

Pour plus de détails, voir l'entrée Psuedo-Key Neat Freak dans SQL Antipatterns. (note, ceci est un lien vers un livre, dont le texte intégral n'est pas disponible gratuitement).

Questions connexes