[Django] #30002: Dynamic model

3 views
Skip to first unread message

Django

unread,
Nov 30, 2018, 4:53:38 PM11/30/18
to django-...@googlegroups.com
#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.

Django

unread,
Nov 30, 2018, 4:58:40 PM11/30/18
to django-...@googlegroups.com
#30002: Dynamic model
-------------------------------------+-------------------------------------
Reporter: temi4 | Owner: temi4
Type: Uncategorized | Status: assigned
Component: Database layer | Version: 2.1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by temi4):

* owner: nobody => temi4
* status: new => assigned


Old description:

New description:

return False

@classmethod
def create_partition(cls, city_slug):

city_slug = cls.check_city_slug(city_slug)

if cls.check_partition(city_slug):
return new_db_table

return new_db_table

I write method:

ProjectCategoryCountPartition.get_city_model(city)

--

--
Ticket URL: <https://code.djangoproject.com/ticket/30002#comment:1>

Django

unread,
Nov 30, 2018, 4:58:52 PM11/30/18
to django-...@googlegroups.com
#30002: Dynamic model
-------------------------------------+-------------------------------------
Reporter: temi4 | Owner: (none)
Type: Uncategorized | Status: new

Component: Database layer | Version: 2.1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by temi4):

* owner: temi4 => (none)
* status: assigned => new


--
Ticket URL: <https://code.djangoproject.com/ticket/30002#comment:2>

Django

unread,
Nov 30, 2018, 5:02:03 PM11/30/18
to django-...@googlegroups.com
#30002: Dynamic model
-------------------------------------+-------------------------------------
Reporter: temi4 | Owner: (none)
Type: Uncategorized | Status: closed

Component: Database layer | Version: 2.1
(models, ORM) |
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):

* status: new => closed
* resolution: => invalid


Comment:

While partially documented in the wiki dynamic models are not officially
supported.

Please use TicketClosingReasons/UseSupportChannels to help you figure out
if and how Django is at fault as this issue tracker is used to keep track
of bugs and feature requests and isn't a second tier support channel.

--
Ticket URL: <https://code.djangoproject.com/ticket/30002#comment:3>

Reply all
Reply to author
Forward
0 new messages