postgresql 这是psycopg2 cur.mogrify()中的一个bug吗?

2g32fytz  于 2023-01-08  发布在  PostgreSQL
关注(0)|答案(2)|浏览(112)

我认为cur.mogrify()在它生成的字符串中错误地注入了一些。我试图写一个很小的ORM供个人使用,但是我遇到了这个行为,看起来像是一个bug:

class BaseModel():
  def __init__(self):
    self.id = None

  @classmethod
  def find(cls, id):
    sql = 'SELECT * FROM %s WHERE id = %s'
    print (cls.table_name)
    sql = cur.mogrify(sql, (cls.table_name, id))
    return sql

class TestModel(BaseModel):
  table_name = 'test_models'
  def __init__(self, attrs):
    self.test_field = attrs["test_field"]
    super().__init__()

python3 -imodels.py

>>> TestModel.find(1)
test_models
b"SELECT * FROM 'test_models' WHERE id = 1"
>>>

正如你所看到的,TestModel.find(1)后面的第一行按预期打印了类的表,但是cur.mogrify在test_models周围加上了'',这导致数据库抛出了一个错误。我通过使用sql = sql.replace(b"'", b"")删除's来绕过这个bug,但是我认为这是一个烦人的工作。有人能确认这是一个bug还是我遗漏了什么吗?

2j4z5cfb

2j4z5cfb1#

这不是一个bug。请参见下面的示例代码:
只能通过此方法绑定查询值:它不应该被用来合并表名或字段名到查询中(Psycopg会尝试将表名作为字符串值引用,生成无效的SQL)。如果你需要动态生成SQL查询(例如动态选择表名),你可以使用psycopg2.sql模块提供的工具。

ar7v8xwq

ar7v8xwq2#

您可以使用AsIs()获取不带引号的表名:

from psycopg2.extensions import AsIs
...
table_name = 'test_models'
sql = 'SELECT * FROM %s WHERE id = %s'
sql = cur.mogrify(sql, (AsIs(table_name), 1))
print sql

退货:

SELECT * FROM test_models WHERE id = 1

相关问题