"ProgrammingError: syntax error at or near...'" when updating rows in postgres with python dictionary

"ProgrammingError: syntax error at or near...'" when updating rows in postgres with python dictionary

我是 postgres 的新手。我正在尝试使用 Python 字典更新 postgres table 中的行。错误示例:

Traceback (most recent call last):
  File "json_to_sql.py", line 187, in <module>
    logger.debug(c.execute(update_movie_data, movie_vars))
psycopg2.ProgrammingError: syntax error at or near "'genres'"
LINE 1: UPDATE movies SET 'genres' = ARRAY['Comedy'] WHERE original_...
                          ^

无论密钥如何,^ 始终指向 '

词典 movie_dicts 中的条目如下所示:

{'adult': False,
'genres': ['Comedy'],
'original_language': 'pa', 
'original_title': 'Jatts in Golmaal',
'overview': "Jatts in Golmal is an Comedy... [Truncated for brevity.]", 
'production_countries': [],
'release_date': '2003-02-21',
'title': 'Jatts in Golmaal',
'images': '/g5epyphS4WqmwJDIu14EL20gxuc.jpg'}

我在 shell 中使用 psql 创建了数据库。然后,我在 Python:

中顺利创建了 table
create_table_movie = """CREATE TABLE movies (
id SERIAL PRIMARY KEY,
adult TEXT,
original_language TEXT,
original_title TEXT,
title TEXT,
overview TEXT,
release_date DATE,
genres TEXT,
production_countries TEXT,
videos TEXT,
images TEXT
);"""

c.execute(create_table_movie)

之后,我遍历字典中的每个条目。在每个循环中,我首先将电影标题插入 original_title 列。效果很好。

然后,我遍历每个条目以更新刚刚插入其标题的每一行。它失败。代码:

for i in movie_dicts:

    insert_movie_data = "INSERT INTO movies (original_title) VALUES (%s);"
    movie_titles = i['original_title'],
    c.execute(insert_movie_data, movie_titles)

    for k, v in i.items():
        try:
            update_movie_data = "UPDATE movies SET %s = %s WHERE original_title = %s;"
            movie_vars = k, v, i['original_title']
            logger.debug(c.execute(update_movie_data, movie_vars))

        except:
            logger.exception()
            pass

我在 Stack Overflow 上阅读了很多关于此语法错误的类似问题,passing parameters to sql queries. I thought maybe this one 上的文档也最接近我的问题。所以我尝试用 k.replace('\'', "") 甚至 k[1:-1] 删除 '。没用。

我的语法看起来是正确的,但显然不是。想不通。我错过了什么?

@muistooshort 在上面的评论中提供了 link 解决了这个问题:http://initd.org/psycopg/docs/sql.html

编辑:

看起来像使用 %s 作为 table 的占位符给了它单引号,这是语法错误。使用 sql.Identifier().format() 来识别 table 正确地防止了这种情况。页面示例:

from psycopg2 import sql

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