PostgreSQL Schema" www"不存在?

时间:2015-09-13 03:20:54

标签: python postgresql psycopg2

如果你在没有指定架构的情况下执行INSERT,那么从PostgreSQL文档中,它应该是 public 架构。​​

conn = psycopg2.connect(dbname = 'orion',
                host = 'localhost',
                port = 5432,
                user = 'earthling',
                password = 'mysupersecretpassword') 
sql = conn.cursor()

def INSERT(table, info, text):
    date = datetime.date.today()
    query = "INSERT INTO %s (info, text, date) " \
        "VALUES (%s, %s, %s)" %(table, info, text, date)
    sql.execute(query)

INSERT("main", "www.capecod.edu", "test")

出于某种原因,我发现以下错误?

psycopg2.ProgrammingError: schema "www" does not exist

1 个答案:

答案 0 :(得分:3)

您正在使用字符串插值来创建查询。这就是psycopg2执行的内容:

INSERT INTO main (info, text, date)
    VALUES (www.capecod.edu, test, 2015-09-12)

如果这里的错误并不明显,那就是没有引用任何值。这是正确引用的版本:

INSERT INTO main (info, text, date)
    VALUES ('www.capecod.edu', 'test', '2015-09-12')

错误是由不加引号的www.capecod.edu引起的。由于这些点,它被解释为schema.table.column

"对"这样做的方法是使用参数化查询。

query = "INSERT INTO main (info, text, date) VALUES (%s, %s, %s)"
params = (info, text, date)
sql.execute(query, params)

psycopg2将弄清楚应该引用什么以及如何引用。这是一个比单纯插入字符串更安全的选项,这通常会让您对SQL注入攻击持开放态度。

http://initd.org/psycopg/articles/2012/10/01/prepared-statements-psycopg/

不幸的是,您不能仅仅将表名等标识符作为参数输入,因为它们被引用为字符串值,这是错误的SQL语法。我找到了一个答案(python adds "E" to string),指向psycopg2.extensions.AsIs作为一种方法,可以安全地将表名等标识符作为参数传递。不过,我无法在测试中完成这项工作。

如果你走AsIs路线,你应该谨慎检查表名是否有效,如果它们以某种方式来自用户输入。像

这样的东西
valid_tables = ["main", "foo", "bar", "baz"]

if table not in valid_tables:
    return False