2

我想在python中执行postgres查询。表名必须作为参数传递。因为表将在运行时创建。我使用了 dict 查询参数样式。但我得到了一个错误。

 import psycopg2

 CONNECTION_STRING = "dbname='autogist' user='postgres' password=''"
 query = "INSERT INTO %(table)s " +\
            "(vin_id, vin_details_id, price, mileage, dealer_id, created_on, modified_on) " +\
            "VALUES (%(vin_id)s, %(vlookup_id)s, %(price)s, %(mileage)s, %(dealer_id)s,now(),now()) " +\
            "RETURNING id"


params = {"table" : "dealer_vehicle_details_2010_01_02",\
                      "vin_id":"3",\
                      "vlookup_id":"403",\
                      "price":"403",\
                      "mileage":"403",\
                      "dealer_id":"276092"
                  }


 conn=psycopg2.connect(CONNECTION_STRING)
 cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
 cursor.execute(query,params)

追溯:

 ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (262, 0))

---------------------------------------------------------------------------
 ProgrammingError                          Traceback (most recent call last)

 /home/gridlex/workspace/<ipython console> in <module>()

 /usr/local/lib/python2.6/dist-packages/psycopg2/extras.pyc in execute(self, query, vars)
121         self.index = {}
122         self._query_executed = 1
--> 123         return _cursor.execute(self, query, vars)
124 
125     def callproc(self, procname, vars=None):

ProgrammingError: syntax error at or near "E'dealer_vehicle_details_2010_01_02'"
LINE 1: INSERT INTO E'dealer_vehicle_details_2010_01_02' (vin_id, vi...
4

1 回答 1

3

您发送的语句在 d 时必须在语法上有效PREPARE,而带有表名占位符的语句则不是。您不能在准备好的语句中使用占位符作为表名。

您的选择是:

  • 用常规字符串替换替换表名,"double quoted". 对你的报价程序要非常小心;确保它将表名中的任何引号加倍,因此表名double"quote变为"double""quote". 例如。'SELECT * FROM "%s"' % quote_ident(tablename). 您必须自己动手quote_ident,因为 AFAIK psycopg2 没有公开这样的功能。

  • 将表名作为查询参数发送到 PL/PgSQL 函数,该函数用于使用EXECUTE ... USING表名创建动态 SQL 语句。PL/PgSQL 可以使用该quote_ident函数提供比自制实现更安全的引用。

于 2012-10-11T11:58:29.013 回答