#30002: Dynamic model
-------------------------------------+-------------------------------------
               Reporter:  temi4      |          Owner:  nobody
                   Type:             |         Status:  new
  Uncategorized                      |
              Component:  Database   |        Version:  2.1
  layer (models, ORM)                |
               Severity:  Normal     |       Keywords:
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 I have ProjectCategoryCountPartition model
 {{{
 class ProjectCategoryCountPartition(models.Model):

     city_slug = models.CharField(verbose_name=_('City slug'),
 max_length=255, db_index=True)
     domain = models.CharField(verbose_name=_('Site name'), max_length=255)
     category_id = models.PositiveIntegerField(verbose_name=_('Category
 id'))
     name = models.CharField(verbose_name=_('Category project name'),
 max_length=255)
     count = models.PositiveIntegerField(default=0)

     class Meta:
         db_table = "wbtm_projects_category_partition"

     class DefaultMeta:
         db_table = "wbtm_projects_category_partition"
         ATTRIBUTE = {
             'city_slug': models.CharField(verbose_name=_('City slug'),
 max_length=255, db_index=True),
             'domain': models.CharField(verbose_name=_('Site name'),
 max_length=255),
             'category_id':
 models.PositiveIntegerField(verbose_name=_('Category id')),
             'name': models.CharField(verbose_name=_('Category project
 name'), max_length=255),
             'count': models.PositiveIntegerField(default=0)
         }

     @classmethod
     def check_partition(cls, city_slug):
         city_slug = cls.check_city_slug(city_slug)

         default_db_table = cls.DefaultMeta.db_table
         new_db_table = "{}_{}".format(default_db_table, city_slug)

         if new_db_table in connection.introspection.table_names():
             return True

         return False

     @classmethod
     def check_city_slug(cls, city_slug):
         city_slug = city_slug.replace('-', '_')
         if not re.match('^[a-zA-Z0-9_]+?$', city_slug):
             raise Exception('Unsupported city_slug')
         return city_slug

     @classmethod
     def create_partition(cls, city_slug):

         city_slug = cls.check_city_slug(city_slug)

         default_db_table = cls.DefaultMeta.db_table
         new_db_table = "{}_{}".format(default_db_table, city_slug)

         if cls.check_partition(city_slug):
             return new_db_table

         queries = [
             """
             CREATE TABLE {}() INHERITS ({});
             """.format(new_db_table, default_db_table),
         ]

         cursor = connection.cursor()
         for query in queries:
             cursor.execute(query)

         return new_db_table

     @classmethod
     def get_city_model(cls, city_slug):
         city_slug = cls.check_city_slug(city_slug)
         model_name = city_slug.replace('_','')

         db_table = cls.create_partition(city_slug)
         attrs = cls.DefaultMeta.ATTRIBUTE.copy()
         attrs.update({
             '__module__': ProjectCategoryCountPartition.__module__,
             'Meta': type(
                 'Meta',
                 (),
                 dict(
                     # managed=False,
                     db_table=db_table,
                 )
             ),
         })

         return type("ProjectCategoryCountPartition{}".format(model_name),
 (models.Model,), attrs)
 }}}

 I write method:

 {{{
 for city in ['moskva', 'london']:
       ProjectCategoryCountPartitionModel =
 ProjectCategoryCountPartition.get_city_model(project_city.slug)
       print(ProjectCategoryCountPartitionModel.objects.filter(
                     city_slug=city,
                     domain='site.ru',
                     category_id=1,
       ).query)

       data = {'name': 'Cat1', 'count': 1}
       ProjectCategoryCountPartitionModel.objects.update_or_create(
                     city_slug=city,
                     domain='site.ru',
                     category_id=1,
                     defaults=data
       )
 }}}

 But, Second call ProjectCategoryCountPartitionModel, return error query.
 Example:

 {{{
 SELECT "wbtm_projects_category_partition_london"."id",
 "wbtm_projects_category_partition_moskva"."city_slug",
 "wbtm_projects_category_partition_moskva"."domain",
 "wbtm_projects_category_partition_moskva"."category_id",
 "wbtm_projects_category_partition_moskva"."name",
 "wbtm_projects_category_partition_moskva"."count" FROM
 "wbtm_projects_category_partition_london" WHERE
 ("wbtm_projects_category_partition_moskva"."category_id" = 1 AND
 "wbtm_projects_category_partition_moskva"."city_slug" = 'london' AND
 "wbtm_projects_category_partition_moskva"."domain" = 'site.ru')
 }}}

 Why are the previous model fields cached in the new model?

-- 
Ticket URL: <https://code.djangoproject.com/ticket/30002>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/048.b5338e1d1b5a1782c6367bac80a628bc%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to