Vagrant部署pg-app-dev-vm时如何在myapp数据库下创建test schema
问题背景
通过Vagrant克隆对应Github仓库提供的PostgreSQL虚拟机后,尝试创建名为test的新schema时,对象始终被创建在postgres默认数据库下。目标是在自定义的myapp数据库下创建test schema,最初在Vagrant-setup/bootstrap.sh中添加的脚本如下:
cat << EOF | su - postgres -c psql myapp create schema test; EOF
故障原因
脚本逻辑本身没有语法错误,schema被创建到错误库的核心原因通常有两类:
- 执行顺序错误:新增的建schema脚本运行时,
myapp数据库还未完成创建,psql连接指定库失败后会自动回退连接到postgres默认库,后续SQL全部在默认库执行 - 参数解析问题:旧版本psql不会自动识别位置传入的库名参数,加管道传递heredoc内容时,su命令的执行上下文没有正确拿到目标库参数,psql直接连接了默认的
postgres库
修复方案
二选一替换原有脚本即可,注意所有操作myapp库的脚本必须放在创建myapp数据库的脚本段之后执行。
方案1:单行显式传参(最稳定)
# 若myapp库可能未创建,先执行建库,已存在时会静默跳过报错不中断执行 su - postgres -c "psql -c 'CREATE DATABASE myapp;'" 2>/dev/null # 显式通过-d参数指定目标库执行建schema操作,加IF NOT EXISTS避免重复执行报错 su - postgres -c "psql -d myapp -c 'CREATE SCHEMA IF NOT EXISTS test;'"
方案2:修正多行heredoc写法
如果需要在同一段逻辑里执行多条SQL,调整heredoc格式避免参数解析和特殊字符转义问题:
su - postgres -c "psql -d myapp" <<'EOF' CREATE SCHEMA IF NOT EXISTS test; -- 其他需要在myapp库执行的SQL可直接追加在此处 EOF
- 分界符
EOF加单引号,避免shell提前解析SQL中的特殊字符 - 必须加
-d参数显式指定目标数据库,不要依赖位置参数传库名
验证方法
脚本执行完成后,进入虚拟机执行如下命令校验结果:
su - postgres -c "psql -d myapp -c '\dn'"
返回的schema列表中存在test项即表示创建位置正确。
内容的提问来源于stack exchange,提问作者David B
相关产品推荐
相关产品推荐

