Как написать одну функцию для удаления из нескольких sql таблиц, используя python - PullRequest
0 голосов
/ 01 апреля 2020

Я реализую проект базы данных студента, который имеет несколько таблиц, таких как студент, класс, секция и т. Д. c

Я написал функцию delete_table, которая принимает имя и значение таблицы параметров для удаления строки из указанного объекта. c таблица, но в моем коде, похоже, есть какая-то синтаксическая ошибка:

def delete_tables(tab_name,attr,value):
    c.execute("delete from table=:tab_name where attribute=:attr is value=:value ",{'tab_name':tab_name, 'attr': attr, 'value': value})

input: delete_tables ('section', 'sec_name', 'S1')

error текст:

c .execute ("удалить из таблицы =: имя_таблицы, где атрибут =: атрибут = значение =: значение", {"имя_таблицы": имя_таблицы, "атрибут": атрибут, "значение": значение})

sqlite3.OperationalError: рядом с «таблицей»: синтаксическая ошибка

Я перепробовал все упомянутые ответы, и вы предлагаете, чтобы это было также будет небезопасным, даже если это сработает. Поэтому нужно ли мне писать функции для удаления каждой таблицы по отдельности вместо того, чтобы переходить к одной функции, и есть ли какая-либо другая альтернатива этой проблеме, когда мне не нужно продолжать писать n функций для n чисел таблиц ????? Заранее спасибо :))

Ответы [ 3 ]

0 голосов
/ 01 апреля 2020

Вам нужно посмотреть, какая именно команда SQL будет выполнена в методе python. Для вызова метода delete_tables ('section', 'sec_name', 'S1') сгенерированная команда SQL будет

delete from table=section where attribute=sec_name is value=S1

Это будет недопустимая команда в SQL. Правильная команда должна быть

delete from section where sec_name='S1'

Поэтому вам необходимо соответствующим образом изменить функцию python. Изменения, которые необходимо сделать, должны быть следующими:

def delete_tables(tab_name, attr, value):
    c.execute("delete from :tab_name where :attr = ':value'",
        {'tab_name': tab_name, 'attr': attr, 'value':value})
0 голосов
/ 01 апреля 2020

Проблема в том, что вы не можете использовать параметризованные запросы (которые :tab_name) для вещей, отличных от значений (не уверен, что я использую правильный термин): имена таблиц, имена столбцов и SQL ключевые слова запрещено .

  • where age > :max_age в порядке.
  • where :some_col > :max_age это не так.
  • where age :comparison_operator :max_age не в порядке.

Теперь вы можете создать свой собственный запрос, используя строку конкатенация или f строк, но ... ? это огромный, огромный риск инъекции SQL. См. Таблицы Бобби Не говоря уже о том, что объединение значений в SQL строк запроса быстро приводит к проблемам, когда вам приходится иметь дело с символами, числами или None. (None => NULL, символам нужны кавычки, цифры не нужны).

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

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

что-то вроде:

delete_tables(tab_name,attr,value):

   safe_tab_name = my_dict_of_known_table_names[tab_name]

   safe_attr = my_dict_of_known_column_names[attr]

                         # you have to `=`, not `is` here? 
   qry = f"delete from {safe_tab_name} where {safe_attr} = :value "

   # not entirely sure about SQLite's bind/parametrized syntax.
   # look it up if needed.
   c.execute(qry, dict(value = value))

Предполагается, что пользователь только вводит значение напрямую, что, по крайней мере, защищено от SQL инъекции.

0 голосов
/ 01 апреля 2020
def delete_tables(tab_name, attr, value):
    c.execute("delete from " + tab_name + "where " + attr + " = " + value)

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

Надеюсь, это помогло.

Редактировать:

Проверить это SQLite python

Что за c .execute «Выполнить» означает «выполнить» запрос SQL, поэтому вы можете создать что-то вроде c.execute("select * from clients"), если у вас есть таблица clients.

execute делает запрос и выводит набор результатов ( если это так), поэтому, если вы хотите удалить из таблицы, используя обычный запрос SQL, вы наберете в консоли delete from clients where client_id = 12, и этот оператор удалит клиента с идентификатором, равным 12.

Теперь, если вы используете SQLite в python, вы будете делать

c.execute("delete from clients where client_id = 12")

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

tableName = "clients"
field = "client_id"
value = "12" #must be string because you would have to cast it from int in the execute
"""
if value is a varchar you must write
value = "'12'" because the '' are needed.
"""
c.execute("delete from " + tableName + " where " + field + " = " + value)

и в верхней части этого, если вы хотите, чтобы это была функция

def delete_tables(tableName, field, value):
    c.execute("delete from " + tableName+ "where " + field + " = " + value)

Редактировать 2:

комментарий Аарона - это правда, это небезопасно, следующий шаг, который вы бы сделали, это

def delete_tables(tab_name, attr, value):
    #no ':value' (it limits the value to characters)
    c.execute("delete from :tab_name where :attr = :value",
        {'tab_name': tab_name, 'attr': attr, 'value':value})

Это от Ватсала ответа

...