46

我正在尝试自动化一组创建 TEMPLATE 数据库的过程。

我有一组文件(file1、file2、... fileN),每个文件都包含一组创建 TEMPLATE 数据库所需的 pgsql 命令。

文件 (createdbtemplate1.sql) 的内容大致如下所示:

CREATE DATABASE mytemplate1 WITH ENCODING 'UTF8';

\c mytemplate1

CREATE TABLE first_table ( 
 --- fields here ..
);

-- Add C language extension + functions
\i db_funcs.sql

我希望能够编写一个 shell 脚本来执行文件中的命令,这样我就可以编写这样的脚本:

# run commands to create TEMPLATE db mytemplate1
# ./groksqlcommands.sh createdbtemplate1.sql

for dbname in foo foofoo foobar barbar
do
    # Need to simply create a database based on an existing template in this script
    psql CREATE DATABASE $dbname TEMPLATE mytemplate1
done

关于如何做到这一点的任何建议?(你可能已经猜到了,我是一个 shell 脚本新手。)

编辑

为了进一步澄清这个问题,我想知道:

  1. 如何编写 groksqlcommands.sh(从文件运行一组 pgsql cmds 的 bash 脚本)
  2. 如何在命令行基于现有模板创建数据库
4

5 回答 5

59

首先,不要混合psql命令和SQL命令。这些是单独的命令集。有一些技巧可以将它们结合起来(使用 psql 元命令\o\\管道字符串到 shell 中的 psql),但这很快就会让人困惑。

  • 使您的文件仅包含 SQL 命令。
  • 不要CREATE DATABASE在 SQL 文件中包含该语句。单独创建数据库,您有多个文件要在同一个模板数据库中执行。

假设您以 OS 用户身份操作postgres并将 DB 角色postgres用作(默认)Postgres 超级用户,则所有数据库都位于默认端口 5432 上的同一数据库集群中,并且由于默认设置中的设置,该角色postgres具有无密码访问权限。IDENTpg_hba.conf

psql postgres -c "CREATE DATABASE mytemplate1 WITH ENCODING 'UTF8'
                  TEMPLATE template0"

我将新模板数据库基于默认系统模板数据库template0手册中的基础知识在这里。

你的问题

如何(...)从文件中运行一组 pgsql cmd

尝试:

psql mytemplate1 -f file

目录中批量文件的示例脚本文件:

#! /bin/sh

for file in /path/to/files/*; do
    psql mytemplate1 -f "$file"
done

command 选项在文件-fpsql执行 SQL 命令。

如何在命令行基于现有模板创建数据库

psql -c 'CREATE DATABASE my_db TEMPLATE mytemplate1'

command 选项-c使psql执行单个 SQL 命令字符串。可以是多个命令,以;- 终止,将在一个事务中执行,并且只返回最后一个命令的结果。
阅读手册中的 psql 命令选项

如果您不提供要连接的数据库,psql将连接到名为“postgres”的默认维护数据库。在第二个答案中,我们连接到哪个数据库无关紧要。

于 2011-12-21T20:00:39.067 回答
3

你可以echo你的命令到 psql 输入:

for dbname in foo foofoo foobar barbar
do
    echo """
CREATE DATABASE $dbname TEMPLATE mytemplate1
""" | psql
done
于 2011-12-21T18:59:08.097 回答
1

如果你愿意加倍努力,你可能会在sqlalchemy上取得更大的成功。它将允许您使用 python 而不是 bash 构建脚本,这更容易并且具有更好的控制力。

根据评论中的要求:https ://github.com/srathbun/sqlCmd

于 2011-12-21T19:09:59.697 回答
1

将您的 sql 脚本存储在根目录下 使用 dev,tst,prd 参数化 dbs 使用 find 运行所有 pgsql 脚本,如下所示Exit on errors

或者只是从这里git clone 整个工具

于 2017-03-30T19:30:47.643 回答
1

对于你必须这样做的用例....

这是我用于将 JSON 导入 PostgreSQL(WSL Ubuntu)的脚本,它基本上要求您在同一命令行中混合 psql 元命令和 SQL。注意使用有点晦涩的脚本命令,它分配一个伪 tty:

$ more update.sh
#!/bin/bash
wget <filename>.json
echo '\set content `cat $(ls -t <redacted>.json.* | head -1)` \\ delete from <rable>; insert into <table> values(:'"'content'); refresh materialized view <view>; " | PGPASSWORD=<passwd> psql -h <host> -U <user> -d <database>
$ 
于 2020-06-23T19:03:53.783 回答