在Fabric脚本中为psql命令转义引号

3 投票
3 回答
1334 浏览
提问于 2025-04-17 20:13

在这个问题的基础上,我想用一个 fabric 命令来删除我 PostgreSQL 数据库里的所有表。我要运行的 bash 命令是:

#!/bin/bash
TABLES=`psql $PGDB -t --command "SELECT string_agg(table_name, ',') FROM information_schema.tables WHERE table_schema='public'"`

echo Dropping tables:${TABLES}
psql $PGDB --command "DROP TABLE IF EXISTS ${TABLES} CASCADE"

在我的 fab 脚本中,这个命令变成了:

def delete_tables():
    the_command = "SELECT string_agg(table_name, ',') FROM information_schema.tables WHERE table_schema='public'"
    run("TABLES=`psql -U db_user -d db_name $PGDB -t --command %s`" % the_command)

但是出现了一个错误,提示 Peer authentication failed for user "string_agg"。这似乎说明这个命令没有被当作一个命令来处理,而是被当作一个长长的字符串……

我试着把 ' 转换成 '\'',但还是没成功。欢迎任何建议。

3 个回答

0

这段代码应该可以直接使用,不需要其他的导入:

def delete_tables():
run('''psql -U db_user -d db_name $PGDB -t -c "SELECT string_agg(table_name, ',') FROM information_schema.tables WHERE table_schema='public';"''')
4

别花钱去做这种事情。用psycopg就可以了:

import psycopg2

conn = psycopg2.connect(database='db_name', user='db_user')
cur  = conn.cursor()
cur.execute("SELECT string_agg(table_name, ',') FROM ...;")
for record in cur:
    print record
6

使用 pipes.quote() 来给要发送到命令行的内容加上引号。

import pipes
def delete_tables():
    the_command = "SELECT string_agg(table_name, ',') FROM information_schema.tables WHERE table_schema='public'"
    run("TABLES=`psql -U db_user -d db_name $PGDB -t --command %s`" % pipes.quote(the_command))

撰写回答