pysqlite: замена подстановки для имен столбцов или таблиц? - PullRequest
15 голосов
/ 13 января 2012

Используя pysqlite, я делаю процедуру, чтобы сделать что-то с некоторыми данными.Аналогичные операции выполняются с аналогичными полями в нескольких таблицах и столбцах, поэтому я подумал, что могу параметризовать оператор SQL, как показано ниже:

def foo():
  column = 'c'
  table = 't'
  row = 1
  # preferred approach, gives syntax error
  c.execute('SELECT ? FROM ? WHERE id=?', (column, table, row))
  # sanity check, works fine
  c.execute('SELECT c FROM t WHERE id=?', (row))
  # workaround, also works, but is this the right way?
  c.execute('SELECT % FROM % WHERE id=?' % (column, table), row))

Полученная ошибка не очень полезна (sqlite3.OperationalError: near "?": syntax error), но я понимаю: Pysqlite не одобряет использование заполнителей таким образом.

Может ли кто-нибудь указать на то, что здесь происходит, наряду с правильным способом выполнения вышеизложенного?

Ответы [ 2 ]

18 голосов
/ 13 января 2012

Вы просто не можете использовать заполнители для имен столбцов или таблиц. У меня нет авторитетного упоминания об этом - я «знаю» это только из-за того, что попробовал и потерпел неудачу. Это имеет некоторый смысл, хотя:

  • Если бы столбцы и таблица могли быть параметризованы, было бы мало цель подготовки (execute -ing) оператора SQL перед извлечением, так как все части оператора могут быть заменен.
  • Я не уверен насчет pysqlite 1 , но MySQLdb автоматически цитирует все строковые параметры. Имена столбцов и таблиц не должны быть в кавычках. Так что усложнит разбор, требуемый водителем, если он должен решить, будет ли заполнитель представлять имя столбца или таблицы по сравнению с значение, которое требует цитирования.

Короче говоря, вы нашли правильный путь - используйте форматирование строки.

c.execute('SELECT {} FROM {} WHERE id=?'.format(column, table), row))

1 Не все драйверы указывают параметры - oursql нет, поскольку он отправляет SQL и аргументы на сервер отдельно.

2 голосов
/ 23 мая 2012

Как ответил @unutbu, нельзя использовать заполнители для имен таблиц / столбцов. Я предлагаю сделать то, что вы делаете сейчас, но также процитировать имена таблиц, чтобы защитить себя от таблицы или столбца, который может иметь нечетное имя.

Что стандарт SQL говорит об использовании backtick (`)? уже объясняет это до некоторой степени, и, несмотря на мнение в этом ответе, я бы сказал, что в вашем случае цитирование хорошая идея.

...