Initial SQL data are not passed verbatim to DB
|Reported by:||Owned by:||Adrian Holovaty|
|Component:||Database layer (models, ORM)||Version:||master|
|Has patch:||no||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
Model API reference says in section "Providing initial SQL data" the following:
Each SQL file, if given, is expected to contain valid SQL. The SQL files are piped directly into the database after all of the models’ table-creation statements have been executed.
That's not entirely true - SQL from the file is passed to db.cursor.execute() that attempts to replace all %s sequences with parameters. In the case when the initial SQL contains "%" character it fails with:
Failed to install custom SQL for Xyz model: not enough arguments for format string
I took the "naive" way and added sql.replace("%", "%%") just before calling cursor.execute() in django/core/management.py:syncdb(), but that's apparently not the best approach. Digging deeper to the code I realised the MySQLdb.cursor.execute() wouldn't attempt to do the string replacement if args was 'None', however Django passes empty tuple '()' instead, which is not 'None'. I blindly tried to convert () to None on a few places in Django but haven't succeeded and got various other errors instead. I admit neither I know django's Db layer, nor I know what Python DB API standard says about the args parameter to execute...
But something is definitely wrong here because the SQL from file isn't passed verbatim to the database, that's for sure at least for MySQLdb 1.2.1pl2