为什么 pg_restore 忽略 --create ?错误:失败:致命:数据库“new_db”不存在

and*_*abs 27 postgresql psql postgresql-9.3

我正在尝试运行以下命令:

sshpass  -p "pass" ssh  x@1.2.3.4 "pg_dump -Fc -U foo some_db" | pg_restore --create --dbname=new_db
Run Code Online (Sandbox Code Playgroud)

我得到:

failed: FATAL:  database "new_db" does not exist
Run Code Online (Sandbox Code Playgroud)

SCO*_*SCO 30

这是因为这是 pg_restore 的工作方式。

pg_restore 手册内容如下:

-C, --create 在恢复之前创建数据库。如果还指定了 --clean,则在连接之前删除并重新创建目标数据库。

使用此选项时,以 -d 命名的数据库仅用于发出初始 DROP DATABASE 和 CREATE DATABASE 命令所有数据都恢复到出现在存档中的数据库名称

当且仅当不使用 -C 时,-d 才会在给定的数据库中恢复。如果使用 -C,则数据库将用作“启动板”,而不是目标。

  • 澄清一下:无法创建任意数据库名称并使用 `pg_restore` 恢复到它。-C 选项只能创建名称与转储文件中的数据库名称匹配的数据库。要恢复到任意数据库,你必须在运行 `pg_restore --dbname=new_db` 之前在 psql 中运行 `CREATE DATABASE new_db;`。 (13认同)
  • 为什么工具本来可以很简单,却必须令人困惑? (12认同)

小智 11

简而言之,您想要(干净现有):(注意数据库名称是postgres

pg_restore -c -d postgres db.dump
Run Code Online (Sandbox Code Playgroud)

或(创建新的)

pg_restore -C -d postgres db.dump
Run Code Online (Sandbox Code Playgroud)

或(显式创建新的)

createdatabase the_database
pg_restore -d the_database db.dump
Run Code Online (Sandbox Code Playgroud)

看 SCO 说的更多细节。

  • 我可以确认这有效(在编辑之后,并且在修复了“postgres”的拼写错误之后)。`pg_restore -C -d postgres db.dump` 可能看起来很吓人,但它对 postgres 数据库没有任何作用,它只用于初始连接。 (2认同)

lib*_*rce 10

让我重写@Izap 的答案,因为我必须一遍又一遍地阅读所有答案才能弄清楚......

在某些情况下,数据库管理工具需要连接数据库,以便执行维护操作。pg_restore例如,当要求创建我们要将数据恢复到的数据库时,就需要一个。

让我们在这里定义一些术语:

  • 我们为了对其他数据库执行操作而连接的数据库是维护数据库
  • 我们将数据恢复到的数据库就是目标数据库

所以我看到的问题pg_restore是它对两个完全不同的东西使用相同的语义(相同的选项参数)。

-d/使用时--dbname理解为维护数据库。--create然而,当它不被使用时,--dbname突然成为目标数据库

为了清楚起见,让我们在 shell 中定义这些:

MAINTENANCE_DB=postgres
TARGET_DB=the_database
Run Code Online (Sandbox Code Playgroud)

所以你有了:

# Clean the target database, then restore into it
pg_restore --clean --dbname $TARGET_DB db.dump
Run Code Online (Sandbox Code Playgroud)
  • 或者
# Create the database (which name is extracted from the dump)
pg_restore --create --dbname $MAINTENANCE_DB db.dump
Run Code Online (Sandbox Code Playgroud)
  • 或者
# Create explicitly the database first
createdb $TARGET_DB
# Restore into that freshly created database (ignoring the name in the dump)
pg_restore --dbname $TARGET_DB db.dump
Run Code Online (Sandbox Code Playgroud)

这意味着仅通过删除该--create选项,人们可能会无意中pg_restore使用维护数据库作为目标数据库

我希望他们选择--maintenance-db像 in 一样使用createdb,始终用于--dbname目标。