Search code examples
postgresqlpsycopg2python-3.7

Is this a bug in psycopg2 cur.mogrify()?


I think that cur.mogrify() is improperly injecting some 's into the string it generates. I'm trying to write a tiny little ORM for personal use but I ran into this behavior that seems like it could be a 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 -i models.py

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

As you can see, the first line after TestModel.find(1) prints the class's table as expected, but then the cur.mogrify puts in '' around test_models which causes the database to throw an error. I got around this bug by using sql = sql.replace(b"'", b"") to delete the 's but I think that's an annoying work around. Can anyone confirm if this is a bug or am I missing something?


Solution

  • It is not a bug. See the example code 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.