"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])
我是 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:
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])