Одна модель Django, несколько таблиц? - PullRequest
24 голосов
/ 18 февраля 2011

У меня есть несколько временных таблиц в базе данных MySQL, которые используют одну и ту же схему и имеют динамические имена. Как бы я использовал Django для взаимодействия с этими таблицами? Может ли одна модель извлекать данные из нескольких таблиц?

Ответы [ 2 ]

22 голосов
/ 18 февраля 2011

Я думаю, вы могли бы создать заводскую функцию, которая бы возвращала вашей модели динамическую db_table .

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 не создает новый экземпляр атрибута класса _meta каждый раз, когда вызывается эта функция. Создание нового экземпляра для _meta зависит от имени класса (Django должен где-то его кешировать). Метакласс может использоваться для изменения имени класса во время выполнения:

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

не уверен, может ли он быть установлен динамически для уже определенного класса. Я сам этого не делал, но это может сработать.

Вы можете установить это в любое время.

>>> MyModel._meta.db_table = '10293847_table'
>>> MyModel.objects.all()
7 голосов
/ 02 апреля 2015

Динамически создайте модель для вашей таблицы.

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

и вы можете начать запрашивать базу данных.

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)...']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...