[Django] #29092: Issues with ManyToMany Models for different apps with same table names

48 views
Skip to first unread message

Django

unread,
Jan 30, 2018, 5:26:50 PM1/30/18
to django-...@googlegroups.com
#29092: Issues with ManyToMany Models for different apps with same table names
-------------------------------------------------+------------------------
Reporter: Elizaveta Kishchukova | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 1.11
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------------------+------------------------
This code results in errors during integrity checks when there are apps
using models with same m2m table name.

in django/db/models/fields/related.py, lines 1441-1453:
{{{
def _check_table_uniqueness(self, **kwargs):
if isinstance(self.remote_field.through, six.string_types) or not
self.remote_field.through._meta.managed:
return []
registered_tables = {
model._meta.db_table: model
for model in
self.opts.apps.get_models(include_auto_created=True)
if model != self.remote_field.through and model._meta.managed
}
m2m_db_table = self.m2m_db_table()
model = registered_tables.get(m2m_db_table)
# The second condition allows multiple m2m relations on a model if
# some point to a through model that proxies another through
model.
if model and model._meta.concrete_model !=
self.remote_field.through._meta.concrete_model:
}}}

Example:

Set up:
app1.SomeModel with table name "some_table_name" (using database 1)
app2.SomeModel with table name "some_table_name" (using database 2)
app1.Y with field xs = models.ManyToManyField('X', through='SomeModel')
app2.Y with field xs = models.ManyToManyField('X', through='SomeModel')

{{{
ERRORS:
app1.Y.xs: (fields.E340) The field's intermediary table 'some_table_name'
clashes with the table name of 'app2.SomeModel'.
app2.Y.xs: (fields.E340) The field's intermediary table 'some_table_name'
clashes with the table name of 'app1.SomeModel'.
}}}

Notice how it compares models of **different apps**. This dictionary ought
to at least use something like 'app_name.table_name' for key.

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

Django

unread,
Jan 30, 2018, 5:38:05 PM1/30/18
to django-...@googlegroups.com
#29092: Issues with ManyToMany Models for different apps with same table names
-------------------------------------+-------------------------------------
Reporter: Elizaveta | Owner: nobody
Kishchukova |

Type: Uncategorized | Status: new
Component: Uncategorized | Version: 1.11
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
-------------------------------------+-------------------------------------
Description changed by Elizaveta Kishchukova:

Old description:

New description:

Example:

to at least use something like 'database.table_name' or
'app_name.table_name' for key.

--

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

Django

unread,
Jan 31, 2018, 2:17:27 PM1/31/18
to django-...@googlegroups.com
#29092: Issues with ManyToMany Models for different apps with same table names
-------------------------------------+-------------------------------------
Reporter: Elizaveta | Owner: nobody
Kishchukova |
Type: Uncategorized | Status: new
Component: Database layer | Version: 1.11
(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 Tim Graham):

* component: Uncategorized => Database layer (models, ORM)


Comment:

If I understand correctly, the only thing preventing the tables from
clashing in your case is the database router. I'm not sure if it's worth
trying to have this check consult database routers. This doesn't seem like
a common setup, so the best solution might be for you to add that check to
`SILENCED_SYSTEM_CHECKS`.

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

Django

unread,
Feb 3, 2018, 5:59:00 PM2/3/18
to django-...@googlegroups.com
#29092: Clashing table name checks don't account for database routers

-------------------------------------+-------------------------------------
Reporter: Elizaveta | Owner: nobody
Kishchukova |
Type: Bug | Status: closed

Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | Resolution: wontfix

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 Tim Graham):

* status: new => closed
* resolution: => wontfix
* type: Uncategorized => Bug


Comment:

Feel free to reopen and offer a patch for evaluation if you think the
implementation is straightforward. I guess any solution can't be perfect
since we won't have access to the `instance` hint at check time.

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

Reply all
Reply to author
Forward
0 new messages