Проблема в том, что вы используете параметризацию DB-API для вещей, которые не являются данными SQL. Когда вы делаете что-то вроде:
cursor.execute('INSERT INTO table_foo VALUES (%s, %s)', (col1, col2))
Модуль DB-API (интерфейс django для любой используемой вами базы данных, в данном случае) будет знать, что нужно экранировать содержимое 'col1' и 'col2' соответствующим образом и заменять% s на них. Обратите внимание, что вокруг% s нет кавычек. Но это работает только для SQL data , но не для SQL метаданных , таких как имена таблиц и имена последовательностей, потому что они должны быть заключены в кавычки по-разному (или не должны вообще). Когда вы это делаете
cursor.execute('INSERT INTO "%s" VALUES (%s, %s)', (tablename, col1, col2))
имя таблицы заключено в кавычки, как будто вы подразумеваете, что это строковые данные для вставки, и в итоге вы получите, например, «table_foo». Вам нужно разделить ваши метаданные SQL, которые являются частью запроса, и ваши данные SQL, которых нет, например:
sql = 'INSERT INTO TABLE "%s" VALUES (%%s, %%s)' % (tablename,)
cursor.execute(sql, (col1, col2))
Обратите внимание, что, поскольку параметром внешнего интерфейса DB-API django является 'pyformat' (он использует% s для заполнителей), вам необходимо избегать их при форматировании строки для создания SQL, который вы хотите выполнить. И обратите внимание, что это не защищает от атак SQL-инъекций, когда вы берете имя таблицы из небезопасного источника и не проверяете его.