4

当使用 psycopg2 使用其格式化选项在 postgres 中创建变量类型名称时,由于对象名称的错误字符串格式化而引发错误。是否不允许在查询参数中使用 %s 传入名称?

我写的确实解决了我的问题的代码如下(只是寻找一种更好的方法来解决这个问题)

cursor.execute("CREATE TYPE {0} AS ENUM %s".format(name), (tuple(set([e.upper() for e in elements])),))
4

3 回答 3

2

实际上,您永远不应该对查询进行 python 格式化,而是让psycopg2来做。这是制作它的方法:http: //initd.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries即:

cur.execute("INSERT INTO numbers VALUES (%s)", (42,))

psycopg2.sql从 2.7 版本开始,可以通过该模块获得一些高级格式化可能性:http: //initd.org/psycopg/docs/sql.html

于 2017-01-09T15:46:09.797 回答
1

如您所料,您不能将表名之类的内容作为查询参数传递。

它们作为协议级别的绑定参数发送,并且(关键)查询必须可解析为有效的 SQL,并将它们作为 placeholders。就好像您要运行 SQL 级别PREPARE然后将EXECUTE. 您必须在准备之前将它们格式化为 SQL 字符串,并使用适当的标识符引用。

双引号您要替换的标识符,并注意您正在传递的字符串中可能出现的双引号,这可能会过早地结束您的引用序列。这些必须加倍。例如,对于some"table您将使用的表名:

 'SELECT * FROM "{0}"'.format('some""table');

SQL注入是一个非常严重的风险;你必须让你的报价完全正确。quote_ident理想情况下,找到 PostgreSQL SQL 函数的客户端等效项。

请注意,双引号标识符区分大小写。通过始终使用双引号来确保您在数据库中使用相同的大小写创建它们,不要混合使用带引号和不带引号的标识符。

于 2012-10-08T09:37:21.677 回答
0

我也遇到了这个问题,并写了一篇简短的博客文章,其中介绍了使用字符串格式连接到远程数据库,但是这个问题和我的解决方案适用于需要将变量传递给 SQL 命令的任何情况。

以下是我解决此问题的方法:

import psycopg2 as db
import sys

my_host = 'ec2-190-111-829-829.compute-1.amazonaws.com'
my_dbname = 'myDBNameGoesHere'
my_user = 'myUsernameGoesHere'
my_password = 'myPasswordGoesHere'
remote_connection_str = 'host={0} dbname={1} user={2} password={3}'.format(my_host, my_dbname, my_user, my_password)

if __name__ == '__main__':
     try:
          remote_connection = db.connect(remote_connection_str)
          cursor = remote_connection.cursor()
          cursor.execute('SELECT version()')
          version = cursor.fetchone()
          print "\n"
          print "Successful connection to database."
          print "Database information:\n", version
          print "\n"

     except db.DatabaseError, e:
          print 'Error %s' % e
          sys.exit(1)

     finally:
          if remote_connection:
          remote_connection.close()
于 2013-10-07T13:58:21.270 回答