При использовании подстановки DB-API для имени столбца в запросе выбора я не получаю ожидаемое значение, а имя столбца вместо - PullRequest
0 голосов
/ 17 мая 2019

Я использую Python 3.6 и sqlite3 для своего проекта и по какой-то неизвестной мне причине при использовании "?" для подстановки имени столбца я не получаю значение в запросе SELECT, но вместо этого получаю имя столбца в качестве возвращаемого значения.

Я приведу несколько запросов (база данных очень проста) и как я использую подстановку в коде:

#this woks without any issues
c.execute('SELECT item_id FROM Items WHERE Name=?', (data,))

#I have an issue with this
c.execute('SELECT ? FROM Items WHERE Name=?', (column_name, data))

Во втором запросе ожидаемое возвращение - это значение из столбца, но вместо этого я получаю кортеж, который содержит имя столбца вместо значения.

c.fetchone()
#expected return is (2,)
#return which I get is ('Sensor_value',) where 'Sensor_value' is column name

c.fetchall()
#return is [('Sensor_value',)] if someone needed that info

Мне известно, что я могу использовать для этого манипуляции со строками, но я хотел бы знать, почему это не работает, хотя это наиболее интуитивный способ справиться с этим.

Временно я использую следующий код, чтобы обойти эту проблему, поэтому я не смотрю на подобные решения:

c.execute('SELECT {col} FROM Items WHERE Name={na}'\
          .format(col=column_name, na=data))

1 Ответ

0 голосов
/ 17 мая 2019

API-операторы, подготовленные для базы данных, не позволяют вводить имя столбца или таблицы.Это может быть потенциально серьезным нарушением безопасности, потому что тогда внешняя вызывающая сторона может потенциально выполнить SQL для любой таблицы или столбца во всей базе данных.Обходной путь здесь может заключаться в том, чтобы просто иметь оператор if else, который делает соответствующий вызов execute, используя правый столбец:

if column_name == "Sensor_value":
    c.execute('SELECT Sensor_value FROM Items WHERE Name = ?', (data,))
elif column_name == "Sensor_data":
    c.execute('SELECT Sensor_data FROM Items WHERE Name = ?', (data,))
else:
    c.execute('SELECT other FROM Items WHERE Name = ?', (data,))

Таким образом, вы гарантируете, что только поддерживаемые столбцы могут использоваться взапрос.Проблема с вашим временным обходом состоит в том, что, опять же, это позволяет вызывающей стороне потенциально выбирать любой столбец в таблице.В качестве примера, чтобы понять, почему вы этого не хотите, представьте пользовательскую таблицу, которая содержит конфиденциальную информацию в одном столбце.Чтобы получить доступ к этому столбцу, все, что должен сделать внешний вызывающий абонент, это просто упомянуть имя этого столбца.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...