将表名作为psycopg2参数传递

2024-06-26 17:53:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下代码,使用pscyopg2:

sql = 'select %s from %s where utctime > %s and utctime < %s order by utctime asc;'
data = (dataItems, voyage, dateRangeLower, dateRangeUpper)
rows = cur.mogrify(sql, data)

这将输出:

select 'waterTemp, airTemp, utctime' from 'ss2012_t02' where utctime > '2012-05-03T17:01:35+00:00'::timestamptz and utctime < '2012-05-01T17:01:35+00:00'::timestamptz order by utctime asc;

当我执行这个命令时,它就结束了——这是可以理解的,因为表名周围的引号是非法的。

有没有一种方法可以合法地将表名作为参数传递,或者我需要(明确警告)字符串连接,即:

voyage = 'ss2012_t02'
sql = 'select %s from ' + voyage + ' where utctime > %s and utctime < %s order by utctime asc;'

为你的见解干杯。


Tags: and代码fromsqldatabyorderwhere
3条回答

this answer您可以这样做:

import psycopg2
from psycopg2.extensions import AsIs

#Create your connection and cursor...

cursor.execute("SELECT * FROM %(table)s", {"table": AsIs("my_awesome_table")})

表名不能作为参数传递,但其他的都可以。因此,表名应该在应用程序中硬编码(不要接受输入或使用程序之外的任何内容作为名称)。你的代码应该能解决这个问题。

如果您有正当理由使用外部表名,请确保不允许用户直接输入。也许可以传递一个索引来选择一个表,或者以其他方式查找表名。不过,你应该谨慎行事。这是可行的,因为周围的表名相对较少。找到一种方法来验证表名,应该没问题。

可以这样做,看看表名是否存在。这是一个参数化版本。只需确保在运行SQL代码之前执行此操作并验证输出。这个想法的一部分来自this answer

SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' and table_name=%s LIMIT 1

根据官方文件:

If you need to generate dynamically an SQL query (for instance choosing dynamically a table name) you can use the facilities provided by the psycopg2.sql module.

sql模块是psycopg2版本2.7中的新模块。它有以下语法:

from psycopg2 import sql

cur.execute(
    sql.SQL("insert into {} values (%s, %s)")
        .format(sql.Identifier('my_table')),
    [10, 20])

更多信息:http://initd.org/psycopg/docs/sql.html#module-psycopg2.sql

[更新2017-03-24:AsIs不应用于表示表或字段名称,应使用新的sql模块:https://stackoverflow.com/a/42980069/5285608]

另外,根据psycopg2文档:

Warning: Never, never, NEVER use Python string concatenation (+) or string parameters interpolation (%) to pass variables to a SQL query string. Not even at gunpoint.

相关问题 更多 >