Search code examples
python-3.xpeewee

Why does PeeWee quote table names?


I'm trying to integrate PeeWee with SQL Relay and I've run into the issue where PeeWee creates SQL statements with double quotes around table names.

Here's some sample code

from peewee import BooleanField
from peewee import CharField
from peewee import DateField
from peewee import ForeignKeyField
from peewee import Model
from SQLRelay import PySQLRDB
from sqlrelay_ext import SQLRelayDatabase

DB = SQLRelayDatabase('test2', host='<hostname>', user='<username>', password='<password>')

class Person(Model):
    name = CharField()
    birthday = DateField()
    is_relative = BooleanField()

    class Meta:
        database = DB

class Pet(Model):
    owner = ForeignKeyField(Person, backref='pets')
    name = CharField()
    animal_type = CharField()

    class Meta:
        database = DB

DB.connect()
Person.create_table(safe=False)
Pet.create_table(safe=False)

Here's a sample stack trace.

Query: CREATE TABLE "person" ("id" INTEGER NOT NULL PRIMARY KEY, "name" VARCHAR(255) NOT NULL, "birthday" DATE NOT NULL, "is_relative" SMALLINT NOT NULL)
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/peewee.py", line 2576, in execute_sql
    cursor.execute(sql, params or ())
  File "/usr/local/lib/python3.6/site-packages/SQLRelay/PySQLRDB.py", line 177, in execute
    raise DatabaseError('<pre>%s</pre>' % the_error)
SQLRelay.PySQLRDB.DatabaseError: <pre>Server message: Incorrect syntax near 'person'. severity(0) number(102) state(1) line(1)  Server Name:ubuntu-mssql  Procedure Name:</pre>

While i know this is ANSI standard, it is unfortunately not well supported by many database clients. Is there a specific reason PeeWee does this? Is it possible to create a custom database adapter that could exclude the double quotes?

Any help would be greatly appreciated.


Solution

  • SQLRelay is not familiar to me. Peewee quotes table names (and other entities) for a couple reasons:

    • It's well-supported by the databases peewee supports out-of-the-box.
    • So you can use SQL reserved words as identifiers or aliases
    • In the event your table/column contains whitespace (which has been reported believe it or not...people do weird stuff).

    Without keeping a rather comprehensive list of all SQL reserved words, Peewee won't know when quotes are strictly required versus being optional. This was discussed in a GH issue a while back. I chose not to implement conditional quoting as I didn't want to maintain a special-case plus a big list of reserved words.

    You could possibly override the execute_sql() method on your database-class and use a regex to strip all quotes before sending them to the database driver, but that feels a little funky. You could also override the database get_sql_context() method to provide your own SQL-generating context which could possibly also handle de-quoting identifiers.

    EDIT: looks like you're using sql server? You could try turning "SET QUOTED_IDENTIFIER": https://learn.microsoft.com/en-us/sql/t-sql/statements/set-quoted-identifier-transact-sql?view=sql-server-2017