Psycopg2字符串格式,带有用于创建类型的变量名称

时间:2012-10-07 17:40:50

标签: python postgresql list-comprehension psycopg2

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

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

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

3 个答案:

答案 0 :(得分:1)

(2)与PostgreSQL完全无关,也许可以编辑出这个问题并将其发布在一个新问题中?我会回答(1)。

正如您所猜测的那样,您无法将表名等内容作为查询参数传递。

它们作为协议级绑定参数发送,并且(严格地)查询必须可解析为有效的SQL,并将它们作为占位符。就好像你要运行SQL级PREPARE然后分开EXECUTE一样。在准备之前,必须使用适当的标识符引用将它们格式化为SQL字符串。

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

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

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

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

答案 1 :(得分:1)

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

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

从2.7版本开始,psycopg2.sql模块提供了一些高级格式化功能:http://initd.org/psycopg/docs/sql.html

答案 2 :(得分:0)

我也遇到了这个问题并编写了一个简短的blog post,其中包含使用字符串格式化与远程数据库的连接,但是这个问题和我的解决方案适用于需要将变量传递给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()