2011-02-18 3 views
22

J'ai plusieurs tables temporaires dans une base de données MySQL qui partagent le même schéma et ont des noms dynamiques. Comment utiliser Django pour interagir avec ces tables? Un seul modèle peut-il tirer des données de plusieurs tables?Modèle Django simple, plusieurs tables?

+0

Vous pouvez le définir dynamiquement comme mis à jour ci-dessous. –

Répondre

21

Vous pourriez, je crois, faire une fonction usine qui renverrait votre modèle avec un db_table dynamique.

def getModel(db_table): 
    class MyClass(models.Model): 
    # define as usual ... 
    class Meta: 
     db_table = db_table 

    return MyClass 

newClass = getModel('29345794_table') 
newClass.objects.filter(... 

EDIT: Django ne crée pas une nouvelle instance de la classe de _meta attribuer à chaque fois que cette fonction est appelée. Créer une nouvelle instance pour _meta dépend du nom de la classe (Django doit le mettre en cache quelque part). Une méta-classe peut être utilisé pour changer le nom de la classe lors de l'exécution:

def getModel(db_table): 
    class MyClassMetaclass(models.base.ModelBase): 
    def __new__(cls, name, bases, attrs): 
     name += db_table 
     return models.base.ModelBase.__new__(cls, name, bases, attrs) 

    class MyClass(models.Model): 
    __metaclass__ = MyClassMetaclass 

    class Meta: 
     db_table = db_table 

    return MyClass 

ne sais pas si elle peut être réglée de manière dynamique sur une classe déjà définie. Je ne l'ai pas fait moi-même mais ça pourrait marcher.

Vous pouvez définir cette chaque fois.

>>> MyModel._meta.db_table = '10293847_table' 
>>> MyModel.objects.all() 
+1

Je pense que votre première solution est mieux dans ma situation, car je vais avoir un certain nombre de tableaux qui doivent être interfacé avec et je ne suis pas sûr que la mise est une solution dynamique de thread-safe. Le problème que j'ai découvert est qu'il y a des résultats étranges lors des tests, à savoir que des querelles doivent être faites pour que les projectiles soient chargés, et même là, il y a un comportement étrange. – exupero

+1

Pour votre première solution, il semble que 'db_table' soit bloqué à tout ce qui est assigné pour la première fois. Il peut être réaffecté, mais il est réaffecté pour chaque instance de la classe (en d'autres termes, il semble qu'il n'y ait qu'une instance de '_meta'). – exupero

+0

La deuxième solution fonctionne pour moi. Enregistrement d'enregistrement: myClass = get_model ('tableName') t = myClass (description = 'nice' # valeur de la colonne t.save() –

7

Créez dynamiquement un modèle pour votre table.

from django.db import models 
from django.db.models.base import ModelBase 

def create_model(db_table): 

    class CustomMetaClass(ModelBase): 
     def __new__(cls, name, bases, attrs): 
      model = super(CustomMetaClass, cls).__new__(cls, name, bases, attrs) 
      model._meta.db_table = db_table 
      return model 

    class CustomModel(models.Model): 

     __metaclass__ = CustomMetaClass 

     # define your fileds here 
     srno = models.IntegerField(db_column='SRNO', primary_key=True) 

    return CustomModel 

et vous pouvez commencer à interroger la base de données.

In [6]: t = create_model('trial1') 

In [7]: t._meta.db_table 
Out[7]: 'trial1' 

In [8]: t.objects.all() # default db 
Out[8]: [<CustomModel: CustomModel object>, '(remaining elements truncated)...'] 

In [9]: t.objects.using('test').all() # test db 
Out[9]: [<CustomModel: CustomModel object>, '(remaining elements truncated)...'] 
+1

Il est la meilleure réponse. Je l'ai conduit dans le code source Django et a constaté que tout modèle hérite de 'models.Model' sera mise en mémoire cache. donc,' est nécessaire méta class' pour définir différents modèle 'name' (clé de cache) et définissez différent 'model._meta.db_table'. – WeizhongTu

Questions connexes