使用另一个数据库中的数据替换除一个数据库之外的所有数据库表

时间:2012-10-27 10:16:29

标签: sql django postgresql database-restore

我有一个Django应用程序,其数据库正在进行有效的手动开发(它是一个语言学习应用程序,因此它存储词汇,语法概念等)。我更喜欢在我当地的django / postgres环境中进行开发。

但是,我不想经常从实时版本中删除用户表格。

我对Postgres很新,所以请不要假设我知道我在这里做什么 - 某种架构会是正确的方法吗?

1 个答案:

答案 0 :(得分:1)

要仅备份一个表,请在数据库中使用COPY

COPY user_tbl TO '/path/to/file';
来自shell的

pg_dump

pg_dump -t user_tbl mydb > user_tbl.sql

然后删除数据库,恢复新版本,清空user_tbl并使用COPY FROM恢复一个表:

COPY user_tbl FROM  '/path/to/file';

或使用psql的shell中的一个表恢复备份:

psql -f user_tbl.sql mydb

识别依赖表

又快又脏

没有“COPY ... CASCADE”这样的东西。识别依赖表的最简单方法是启动一个事务,调用TRUNCATE tbl CASCADE并记录你得到的通知:

BEGIN;
TRUNCATE user_tbl CASCADE;

NOTICE:  truncate cascades to table "tbl1"
NOTICE:  truncate cascades to table "tbl2"
NOTICE:  truncate cascades to table "tbl3"

然后回滚事务 - 所以实际上没有任何改变:

ROLLBACK;

小心。如果你COMMIT截断了。

慢而且确定

嗯,实际上并不“慢”,但代码要复杂得多。但是,这并没有对所涉及的表进行独占锁定,因此它更清晰,更安全:

WITH RECURSIVE x AS (
    SELECT conrelid::regclass
    FROM   pg_constraint
    WHERE  confrelid = 'user_tbl'::regclass

    UNION
    SELECT p.conrelid::regclass
    FROM   x
    JOIN   pg_constraint p ON p.confrelid = x.conrelid
    )
SELECT conrelid::text AS tbl
FROM   x;

返回:

tbl
------
tbl1
tbl2
tbl3

我在目录表recursive CTE上使用pg_constraint(需要PostgreSQL 8.4或更高版本),因为每个表都可以依次具有依赖关系。
使用UNION而不是UNION ALL来避免对可能直接或间接与多个外键链接的表进行多次评估。