﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
22611	sqlclear command tries to drop non-existing constraint with ForeignKey to self (postgresql)	Vidir Valberg Gudmundsson		"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.)"	Bug	closed	Core (Management commands)	1.7-beta-2	Normal	wontfix			Accepted	0	0	0	0	0	0
