这是 psycopg2 cur.mogrify() 中的错误吗?
Is this a bug in psycopg2 cur.mogrify()?
我认为 cur.mogrify() 不正确地将一些 ' 注入到它生成的字符串中。我正在尝试编写一个供个人使用的小型 ORM,但我 运行 发现这种行为似乎是一个错误:
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 -i models.py
>>> TestModel.find(1)
test_models
b"SELECT * FROM 'test_models' WHERE id = 1"
>>>
如您所见,TestModel.find(1)
之后的第一行按预期打印了 class 的 table,但随后 cur.mogrify 在 test_models 导致数据库抛出错误。我通过使用 sql = sql.replace(b"'", b"")
删除 's 解决了这个错误,但我认为这是一个烦人的解决方法。谁能确认这是错误还是我遗漏了什么?
这不是错误。请参阅示例代码 after this passus:
Only query values should be bound via this method: it shouldn’t be used to merge table or field names to the query (Psycopg will try quoting the table name as a string value, generating invalid SQL). If you need to generate dynamically SQL queries (for instance choosing dynamically a table name) you can use the facilities provided by the psycopg2.sql module.
您可以使用 AsIs() 来获取不带引号的 table 名称:
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
Returns:
SELECT * FROM test_models WHERE id = 1
我认为 cur.mogrify() 不正确地将一些 ' 注入到它生成的字符串中。我正在尝试编写一个供个人使用的小型 ORM,但我 运行 发现这种行为似乎是一个错误:
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 -i models.py
>>> TestModel.find(1)
test_models
b"SELECT * FROM 'test_models' WHERE id = 1"
>>>
如您所见,TestModel.find(1)
之后的第一行按预期打印了 class 的 table,但随后 cur.mogrify 在 test_models 导致数据库抛出错误。我通过使用 sql = sql.replace(b"'", b"")
删除 's 解决了这个错误,但我认为这是一个烦人的解决方法。谁能确认这是错误还是我遗漏了什么?
这不是错误。请参阅示例代码 after this passus:
Only query values should be bound via this method: it shouldn’t be used to merge table or field names to the query (Psycopg will try quoting the table name as a string value, generating invalid SQL). If you need to generate dynamically SQL queries (for instance choosing dynamically a table name) you can use the facilities provided by the psycopg2.sql module.
您可以使用 AsIs() 来获取不带引号的 table 名称:
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
Returns:
SELECT * FROM test_models WHERE id = 1