#22611: sqlclear command tries to drop non-existing constraint with ForeignKey to self (postgresql) --------------------------------------------+------------------------ Reporter: valberg | Owner: nobody Type: Bug | Status: new Component: Core (Management commands) | Version: 1.7-beta-2 Severity: Normal | Keywords: Triage Stage: Unreviewed | Has patch: 0 Easy pickings: 0 | UI/UX: 0 --------------------------------------------+------------------------ Having the following model (in an app called test_app):
{{{ class Foo(models.Model): bar = models.ForeignKey('self') }}} The `sqlclear` management command returns: {{{ $ ./manage.py sqlclear testapp BEGIN; ALTER TABLE "testapp_foo" DROP CONSTRAINT "bar_id_refs_id_83e148c5"; DROP TABLE "testapp_foo"; COMMIT; }}} Piping this into `psql` results in the following error: {{{ > ./manage.py sqlclear testapp | psql -U django -h localhost django BEGIN ERROR: constraint "bar_id_refs_id_83e148c5" of relation "testapp_foo" does not exist ERROR: current transaction is aborted, commands ignored until end of transaction block ROLLBACK }}} Checking the table in `psql` reveals: {{{ django=# \d testapp_foo Table "public.testapp_foo" Column | Type | Modifiers --------+---------+---------------------------------------------------------- id | integer | not null default nextval('testapp_foo_id_seq'::regclass) bar_id | integer | not null Indexes: "testapp_foo_pkey" PRIMARY KEY, btree (id) "testapp_foo_bar_id" btree (bar_id) Foreign-key constraints: "testapp_foo_bar_id_fkey" FOREIGN KEY (bar_id) REFERENCES testapp_foo(id) DEFERRABLE INITIALLY DEFERRED Referenced by: TABLE "testapp_foo" CONSTRAINT "testapp_foo_bar_id_fkey" FOREIGN KEY (bar_id) REFERENCES testapp_foo(id) DEFERRABLE INITIALLY DEFERRED }}} So it seems that the `sqlclear` command generates a different name for the constraint than it actually is. I'm guessing that postgresql is in charge of naming the constraint. At least looking at the output of the `sqlall` command, there is no indication of Django doing any naming. {{{ $ ./manage.py sqlall testapp BEGIN; CREATE TABLE "testapp_foo" ( "id" serial NOT NULL PRIMARY KEY, "bar_id" integer NOT NULL REFERENCES "testapp_foo" ("id") DEFERRABLE INITIALLY DEFERRED ) ; CREATE INDEX "testapp_foo_bar_id" ON "testapp_foo" ("bar_id"); COMMIT; }}} I've figured out that the "wrongful" naming is done in `django.db.backends.creation.BaseDatabaseCreation.sql_remove_table_constraints`, but there my knowledge of Djangos ORM stops :) It might be worth noting that doing a simple DROP statement drops the table just fine. So maybe the ALTER statement isn't necessary?: {{{ $ echo 'BEGIN; DROP TABLE "testapp_foo"; COMMIT;' | psql -U django -h localhost django BEGIN DROP TABLE COMMIT }}} (I'm using Django 1.7b3 installed with `pip install git+https://github.com/django/django@stable/1.7.x#egg=Django`, but it is not listed in the version list.) -- Ticket URL: <https://code.djangoproject.com/ticket/22611> 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 django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/050.f891029cadf3ed0b34d3157a9ef3a6c6%40djangoproject.com. For more options, visit https://groups.google.com/d/optout.