Psycopg2 不仅接受 None (Nonetype) 作为使用 %s 时可以为 Null 的单元格条目,但不接受 f-strings

pyt*_*ons 2 python postgresql psycopg2 python-3.x

我使用 Psycopg2 将数据插入到 Postgres 数据库中:

params = "ts, price, volume"
entry = (1234567, None, 3)
cur.execute(f"INSERT INTO stock_data ({params}) VALUES {entry};")
Run Code Online (Sandbox Code Playgroud)

我无数次使用这种带有参数和元组条目的 f-string 模式,没有任何问题。

有关其他信息,该price列没有任何约束,并且是numeric(5).

对于这个特定的例子,它给了我错误:

psycopg2.ProgrammingError: column "none" does not exist

我尝试的一切都导致了这个错误。最终起作用的不是使用 f 弦。以下条目有效:

cur.execute(f"INSERT INTO stock_data ({params}) VALUES (%s, %s, %s);", entry)

我的理解是这些是相同的。为什么后者会起作用,但将条目直接包含在INSERT语句中不起作用?

kli*_*lin 5

Format 只是将值插入到一个字符串中:

>>> x = None
>>> f"What should I expect here? {x}"
'What should I expect here? None'
Run Code Online (Sandbox Code Playgroud)

您将已格式化的字符串传递给cur.execute(). 当您传递带有占位符和参数的查询文本时,该函数知道如何转换它们。

>>> cur.mogrify(f"INSERT INTO stock_data ({params}) VALUES {entry};")
b'INSERT INTO stock_data (ts, price, volume) VALUES (1234567, None, 3);'

>>> cur.mogrify(f"INSERT INTO stock_data ({params}) VALUES (%s, %s, %s);", entry)
b'INSERT INTO stock_data (ts, price, volume) VALUES (1234567, NULL, 3);'
Run Code Online (Sandbox Code Playgroud)

您应该始终在 cursor.execute() 中使用占位符和参数,也是为了您自己的安全。阅读将参数传递给 SQL 查询,您可以在其中找到此内容

警告

从不,从不,永远不要使用 Python 字符串连接 (+) 或字符串参数插值 (%) 将变量传递给 SQL 查询字符串。甚至不是在枪口下。