2011-02-18 32 views
22

Tengo varias tablas temporales en una base de datos MySQL que comparten el mismo esquema y tienen nombres dinámicos. ¿Cómo usaría Django para interactuar con esas tablas? ¿Puede un único modelo extraer datos de múltiples tablas?Modelo único de Django, ¿varias tablas?

+0

puede configurarlo dinámicamente como se actualiza a continuación. –

Respuesta

21

Podría, creo, hacer una función de fábrica que devolvería su modelo con un db_table dinámico.

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 no crea una nueva instancia de la clase de _meta atribuir cada vez que esta función se llama. Crear una instancia nueva para _meta depende del nombre de la clase (Django debe almacenarla en caché en algún lugar). Una metaclase se puede utilizar para cambiar el nombre de la clase en tiempo de ejecución:

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 

no estoy seguro si se puede ajustar de forma dinámica en una clase ya definido. No lo he hecho yo mismo, pero podría funcionar.

Puede configurar esto cada vez que lo desee.

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

Creo que su primera solución es mejor en mi situación, ya que tendré varias tablas con las que interactuar y no estoy seguro de que establecerlas dinámicamente sea una solución segura para subprocesos. El problema que he descubierto es que hay resultados extraños cuando se prueban, es decir, que hay que hacer algunas disputas para cargar los accesorios, y aun así hay un comportamiento extraño. – exupero

+1

Para su primera solución, parece que 'db_table' está atascado en lo que se asignó primero. Se puede reasignar, pero se reasigna para cada instancia de la clase (en otras palabras, parece que solo hay una instancia de '_meta'). – exupero

+0

La segunda solución funciona para mí. Guardar registro: myClass = get_model ('tableName') t = myClass (description = 'nice' # establecer el valor de columna t.save() –

7

Cree dinámicamente un modelo para su mesa.

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 

y puede comenzar a consultar la base de datos.

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

Es la mejor respuesta. He accedido al código fuente de Django y he encontrado que cualquier modelo heredado de 'models.Model' se almacenará en caché. Por lo tanto,' meta class' es necesario para establecer diferentes 'nombre de modelo' (clave de caché) y establecer diferente 'model._meta.db_table'. – WeizhongTu