postgres:删除具有外键但没有删除外键表数据的行

时间:2014-01-20 15:11:38

标签: sql database django postgresql django-south

我有postgres数据库,我的应用程序是使用django构建的,我使用south migration来维护数据库架构。我有以下情况:

user_tableuserclickstream_stream具有外键关系,userclickstream_click与user_stream_table具有外键关系。

我想删除userclickstream_streamuserclickstream_click中的所有记录。但我不想删除user_table中的任何记录。完成此任务的最佳方法是什么?

以下是我的user_stream_table的样子:

                                    Table "public.userclickstream_stream"
   Column    |           Type           |                              Modifiers                              
-------------+--------------------------+---------------------------------------------------------------------
 id          | integer                  | not null default nextval('userclickstream_stream_id_seq'::regclass)
 session_key | character varying(40)    | not null
 ip_address  | character varying(40)    | not null
 referrer    | text                     | 
 create_date | timestamp with time zone | not null
 last_update | timestamp with time zone | not null
 user_id     | integer                  | 
Indexes:
    "userclickstream_stream_pkey" PRIMARY KEY, btree (id)
    "userclickstream_stream_session_key_key" UNIQUE CONSTRAINT, btree (session_key)
    "userclickstream_stream_user_id" btree (user_id)
Foreign-key constraints:
    "user_id_refs_id_773d100c" FOREIGN KEY (user_id) REFERENCES auth_user(id) DEFERRABLE INITIALLY DEFERRED
Referenced by:
    TABLE "userclickstream_click" CONSTRAINT "stream_id_refs_id_4c08df60" FOREIGN KEY (stream_id) REFERENCES userclickstream_stream(id) DEFERRABLE INITIALLY DEFERRED

以下是User_click_table的方式

                                    Table "public.userclickstream_click"
   Column    |           Type           |                             Modifiers                              
-------------+--------------------------+--------------------------------------------------------------------
 id          | integer                  | not null default nextval('userclickstream_click_id_seq'::regclass)
 stream_id   | integer                  | not null
 url         | text                     | not null
 path        | text                     | not null
 create_date | timestamp with time zone | not null
Indexes:
    "userclickstream_click_pkey" PRIMARY KEY, btree (id)
    "userclickstream_click_stream_id" btree (stream_id)
Foreign-key constraints:
    "stream_id_refs_id_4c08df60" FOREIGN KEY (stream_id) REFERENCES userclickstream_stream(id) DEFERRABLE INITIALLY DEFERRED

如果有一个好的SQL方法来处理这个问题而不是走向南迁移路线,那将会很棒。如果不是我想做以下事情:

我想只是删除南迁移历史记录表中的记录并使用南方重新构建模式我不确定这是不是正确的方法。但要做到这一点,我需要先放下这两个表。由于外键关系,我可能无法删除表。

让我说放弃它然后我可能能够执行以下操作,因为南迁移历史表没有这两个表的任何记录。

./manage.py schemamigration userclickstream --initial
./manage.py migrate userclickstream

1 个答案:

答案 0 :(得分:2)

见这里:

http://www.postgresql.org/docs/9.3/static/ddl-constraints.html

  

限制和级联删除是两种最常见的选项。 RESTRICT可防止删除引用的行。 NO ACTION表示如果在检查约束时仍存在任何引用行,则会引发错误;如果您未指定任何内容,则这是默认行为。 (这两个选项之间的本质区别在于NO ACTION允许将检查延迟到事务的后期,而RESTRICT则不会。​​)CASCADE指定当删除引用的行时,应自动删除引用它的行同样。还有另外两个选项:SET NULL和SET DEFAULT。当删除引用的行时,这些引用将引用行中的引用列分别设置为空值或其默认值。请注意,这些不能免除您观察任何约束。例如,如果操作指定SET DEFAULT但默认值不满足外键约束,则操作将失败。

     

类似于ON DELETE,还有ON UPDATE,当引用的列被更改(更新)时会调用它。可能的行动是相同的。在这种情况下,CASCADE意味着应将引用列的更新值复制到引用行中。

     

通常,如果引用行的任何引用列为空,则引用行不必满足外键约束。如果将MATCH FULL添加到外键声明中,则只有当所有引用列都为空时,引用行才会转义满足约束(因此保证将null和非null值混合使MATCH FULL约束失败)。如果您不希望引用行以避免满足外键约束,请将引用列声明为NOT NULL。

     

外键必须引用作为主键或形成唯一约束的列。这意味着引用的列始终具有索引(主键或唯一约束下面的索引);因此,检查引用行是否匹配将是有效的。由于引用表中的行的DELETE或引用列的UPDATE将需要扫描引用表以查找与旧值匹配的行,因此通常也应该对引用列建立索引。因为并不总是需要这个,并且有很多关于如何索引的选择,所以外键约束的声明不会自动在引用列上创建索引。

似乎你只需要设置一个最合适的ON DELETE动作,最适合你的情况。