如何使用终端创建数据库并使用URI连接?

4

URI连接字符串可能非常复杂,这里提供一个标准的例子:

  createdb "postgresql://postgres:postgres@localhost:5432/sandbox"

当然,它不能与createdb一起使用(“template1:FATAL”),这就是问题所在。该URI与psql完美配合,例如。
  psql "postgresql://postgres:postgres@localhost:5432/postgres"

我正在寻找符合预期行为的任何内容,即使命令名称不是createdb


PS1:在我的环境中,即使对于postgres用户,也有密码等信息,并且所有我的脚本都使用URI连接字符串标准,不再使用-U等选项。这个问题的重点是URI标准。使用现代客户端和连接,v9+。

PS2:作为传统和哲学,我们期望PostgreSQL提供的命令具有正交行为psqlpg_dump关于URI是正交的;psqlpg_dumpcreatedb关于-U选项是正交的... 我希望URI的使用也有一些正交性... 或者存在架构缺陷

3个回答

9

clusterdb、createdb、createuser、dropdb、dropuser、reindexdb 和 vacuumdb 是一些封装了 SQL 命令的实用程序命令。虽然它们并没有被正式弃用,但它们并不是人们特别关注的程序之一。如今,大多数人使用某种脚本来完成他们的工作。如果您想要使用客户端程序和 URI 来执行 CREATE DATABASE,则:

psql "postgresql://postgres:postgres@localhost:5432/postgres" -c 'CREATE DATABASE my_test_db'
Null display is "NULL".
CREATE DATABASE

或者使用以下方式传入文件:

psql "postgresql://postgres:postgres@localhost:5432/postgres" -f db_create.sql

更新 2020 年 12 月 05 日

似乎有一个未记录在案的功能现已被揭示。针对这些命令(不是 *user),大多数都有一个 --maintenance-db 选项。从 CREATEDB 开发文档中可以得知:

--maintenance-db=dbname

在创建新数据库时指定要连接到的数据库的名称。如果未指定,则将使用 postgres 数据库;如果该数据库不存在(或者它是正在创建的新数据库的名称),则将使用 template1。它可以是连接字符串,如果是,则连接字符串参数将覆盖任何冲突的命令行选项。

其中,连接字符串可以是 URI


感谢Adrain,展示了“已弃用命令”的视野...在这个背景下,你的回答表明这是一个错误,并且这个错误永远不会被修复...但是我们,用户社区可以通过放弃那些命令来解决它。 - Peter Krauss
一个 bug 是一项承诺但无法正常工作的功能。对于这些程序,不能保证使用 URI 的能力,因为该功能根本不存在。这些程序已经被放弃了。它们主要存在是为了向后兼容,以支持在其他选项出现之前创建的工作流程。 - Adrian Klaver
是的,我同意,我们正在谈论“规范错误”(而不是实现错误)。就像在任何软件开发生命周期中一样,当PostgreSQL增长和发展时,旧的模块或命令规范也必须发展...目前(2020年!)在进化的psql(v12生态系统)和这些古老的命令之间存在规范不一致。每个命令规范中都必须承诺URI。附注:你的答案是正确的,在这里只有哲学讨论。 - Peter Krauss
1
@PeterKrauss。看起来它们是一项未记录但有些损坏的功能。在最新的开发文档createdb下的--maintenance-db=dbname。请参见Postgres Weekly下的“Tom Lane pushed:” 。有几个与连接字符串相关的提交。 - Adrian Klaver

3

https://www.postgresql.org/docs/current/static/app-createdb.html createdb不支持将URI作为dbname,但psql支持: https://www.postgresql.org/docs/current/static/app-psql.html

当您执行以下操作时会发生什么:

 createdb "postgresql://postgres:postgres@localhost:5432/sandbox"

应该将第一个参数按原样读取,并使用此名称创建数据库(对我而言就是这样):

MacBook-Air:~ vao$ psql t -c "\l pos*"
Timing is on.
Pager usage is off.
                                               List of databases
                         Name                          | Owner | Encoding | Collate | Ctype | Access privileges
-------------------------------------------------------+-------+----------+---------+-------+-------------------
 postgres                                              | vao   | UTF8     | C       | UTF-8 |
 postgresql://postgres:postgres@localhost:5432/sandbox | vao   | UTF8     | C       | UTF-8 |

这种行为与手动匹配:

dbname

指定要创建的数据库的名称。

指定要创建的数据库名称,而psql dbname可以是要连接到的数据库URI...


嗨VaoTsun,感谢您的所有解释,但我正在寻找一个“隐藏的解决方案”,因为预期所有命令都将使用URI工作,而不仅仅是psql...所以,如果没有类似于createdb的命令(可以提供URI),那么PostgreSQL中存在架构错误。按照其传统和哲学,我们期望PostgreSQL提供的命令具有正交行为。抱歉表述不够清晰,我编辑了问题以强调重点。 - Peter Krauss
Adrian关于createdb等的评论很重要,"虽然它们还没有被正式弃用,但它们在任何人关心的程序列表中并不是最受关注的"。因此,在这种情况下,你的回答也是有意义的,展示了一个永远不会被修复的错误。用户社区可以通过放弃这些命令,仅使用psql -c直接命令来修复它。附言:你是第一个回答的,所以我选择了你的好答案。我的评论只是为了进行哲学讨论。 - Peter Krauss

0
你可以尝试按照环境变量文档部分所述设置PGHOSTPGHOSTADDRPGPORTPGDATABASEPGUSERPGPASSWORD环境变量。
希望这能有所帮助。

嗨Daniele,它是有意义的并且有效,但问题是“如何使用... URI?”在问题的上下文中,设置变量被排除在外,这不是我想要的替代方案。 - Peter Krauss

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接