【问题标题】:Replace all tables of a database except one, with data from another db用另一个数据库中的数据替换数据库中除一个之外的所有表
【发布时间】:2012-10-17 10:41:00
【问题描述】:

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

但是,我不想不断地从实时版本中清除用户表!

我对 Postgres 很陌生,所以请不要假设我知道我在这里做什么 - 某种模式在这里是正确的方法吗?

【问题讨论】:

    标签: sql django postgresql database-restore


    【解决方案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
    

    识别依赖表

    又快又脏

    没有“复制...级联”之类的东西。识别依赖表的最简单方法是启动事务,调用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
    

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

    【讨论】:

    • @GregPallis:我添加了一些关于如何识别依赖表的内容。
    • 谢谢!这非常有帮助,而且我通过它学习了很多关于 Postgres 的知识。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    • 2012-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多