Opened 19 years ago
Closed 18 years ago
#3480 closed (fixed)
sqlreset drops more tables than it should for GenericRelations to separate apps
| Reported by: | Owned by: | nobody | |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | dev |
| Severity: | Keywords: | ||
| Cc: | Triage Stage: | Accepted | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | yes | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
A model from app A has a GenericRelation to another model in app B. When I reset app A, Django outputs DROP TABLE statements for the model from B. Example:
apps/test/models.py:
from django.db import models from generictestcase.apps.meta.models import Tag class Article(models.Model): tags = models.GenericRelation(Tag)
apps/meta/models.py:
from django.db import models from django.contrib.contenttypes.models import ContentType class Tag(models.Model): content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() object = models.GenericForeignKey()
I use "python manage.py syncdb" to create the database tables (sqlite3 in my case), then "python manage.py sqlreset test" to generate SQL:
BEGIN;
DROP TABLE "meta_tag";
DROP TABLE "test_article";
CREATE TABLE "test_article" (
"id" integer NOT NULL PRIMARY KEY
);
COMMIT;
Django shouldn't drop the "meta_tag" table here, because it lives in the "meta" app.
Attachments (1)
Change History (8)
comment:1 by , 19 years ago
| Resolution: | → duplicate |
|---|---|
| Status: | new → closed |
comment:2 by , 18 years ago
| Resolution: | duplicate |
|---|---|
| Status: | closed → reopened |
This is not duplicate of #3549. #3549 says that 'reset' try to delete the same table more that once.
This ticket shows that generic_relation deletes tables from others applications. For example:
I have application 'comments' with model 'Comment' and generic foreign key. I have two other aplications with models 'Article' and 'Event'. They both have generic relation to Comment.
When I reset application 'articles' then table with comments will be droped, but isn't recreated. In that case I lost all comments for events and will have got errors that comments_comment table is not found. To fix that I need too syncdb.
I found that durning creating tables phase there is chechking that m2m table is not instance of GenericRelation - tables from generic realtion aren't created, but durning deleteing tables phase that is not checked and all m2m tables (including generic relations tables are dropped).
comment:3 by , 18 years ago
This is a how it can be fixed.
def get_sql_delete(app):
...
# Output DROP TABLE statements for many-to-many tables.
for model in app_models:
opts = model._meta
for f in opts.many_to_many:
# check if is not a GenericRel
if not isinstance(f.rel, generic.GenericRel):
if cursor and table_name_converter(f.m2m_db_table()) in table_names:
...
ps. I know that I should submit a patch. Sorry for that.
by , 18 years ago
Patch to check for GenericRel type at deletion (already done at creation)
comment:4 by , 18 years ago
| Has patch: | set |
|---|
comment:5 by , 18 years ago
| Needs tests: | set |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
The patch looks good to me, definitely better than that from #3549. Could you add a regression test for this bug?
comment:6 by , 18 years ago
I just got bitten by this: I reset an app and inadvertently deleted all the comments, even the ones for other apps...
comment:7 by , 18 years ago
| Resolution: | → fixed |
|---|---|
| Status: | reopened → closed |
This is a duplicate of #3549 (which is newer, but has a better description).