【问题标题】:SQL syntax error with psycopg2 (python)psycopg2 (python) 的 SQL 语法错误
【发布时间】:2018-03-07 21:14:41
【问题描述】:

所以我正在尝试编写自己的 sqlite3 到 postgresql 迁移脚本,它将所有表从一个数据库转移到另一个。

我目前看到以下语法错误:

ERROR: syntax error at or near "'name'"
LINE 1: UPDATE django_site SET ('name', 'domain')=('127.0.0.1:8080',...
                                ^

它不太喜欢('name', 'domain') ...我可能在想我缺少一些微妙的东西...

('name', 'domain') 由以下代码行生成:

col = tuple([desc[0] for desc in self.cur_sql3.description])

即,将所有列名作为生成的list,然后转换为tuple 类型。

SQL 查询目前正在这样构建:

cur_psql.execute("UPDATE {0} SET {1}={2} WHERE id={3}".format(table[0], col[1:], row[1:], col[0]))

table[0]表名col[1:] 是除了主 id 键之外的所有内容,row[1:] 是所有行值减去主键,col[0] 是 主键值,例如1,2,3,45

有什么明显的技巧可以避免这个问题吗?

【问题讨论】:

  • 如果从列名中删除' 是否有效?我认为它们不允许用于列。
  • 当我这样做时,我得到“当前事务被中止,命令被忽略直到事务块结束”
  • 可能是因为您当前的事务被中止,并且您的命令被忽略直到事务结束。结束事务 (ROLLBACK) 并重试。

标签: python postgresql python-3.6 psycopg2


【解决方案1】:

您需要将其拆分为单独的 SQL 语句,或者您需要对列值对进行某种循环。我需要更多信息来编写更正的 Python 代码,但您的 SQL 应该如下所示:

UPDATE table SET col = val WHERE id = id_val

你正在做类似的事情:

UPDATE table SET ('col1', 'col2') = ('val1', 'val2')

如果您想在一个语句中更新多个列,您可以这样做:

UPDATE table SET col1 = val1, col2 = val2 WHERE id = id_val

请记住,如果它们是字符列(但如果它们是数字),则需要转义值,如下所示:

UPDATE table SET col1 = 'character value', col2 = 123 WHERE id = 1

最终,这应该通过绑定变量而不是字符串格式来完成,因为字符串格式可能会将您的代码暴露给 SQL 注入攻击(如果这严格来说是您自己运行的实用程序脚本,则可能不必担心,但它是无论如何都要养成的好习惯)。您可以在此处找到 psycopg2 中绑定变量的文档:http://initd.org/psycopg/docs/usage.html#query-parameters

按照我上面的建议会导致这样的结果:

set_clauses = ",".join(["{} = %s".format(col) for col in col[1:]])
query = "update {} set {} where id = {}".format(table[0], set_clauses, row[0])
cur_psql.execute(query, row[1:])

【讨论】:

  • 我想我可以看一下并进行两次更新事务,哪个更有效?
  • Postgrsql documentation 明确提到了括号语法,所以我认为这不是问题。
  • 感谢您指出 @syntonym 我不知道 postgres 中的语法。我的猜测是,在括号中单引号会导致语法错误(这就是错误消息中的列光标指向的位置)
  • @msiadak 我觉得我们越来越近了,但我收到以下语法错误:set_clauses = ",".join([{} = %s for col in col[1:]]) 它指向= ...?
  • 抱歉,我在编辑时点击保存太快了。现在应该修好了。
猜你喜欢
  • 2017-12-03
  • 1970-01-01
  • 2022-12-03
  • 1970-01-01
  • 2018-03-12
  • 2021-09-28
  • 2012-03-10
  • 2020-11-18
  • 2020-07-08
相关资源
最近更新 更多