2015-12-07 4 views
-1

Итак, у меня есть список форматированных строк, которые я хочу вставить в базу данных. Они отформатированы, поэтому база данных будет принимать этот тип строки.Предотвращение SQL-инъекции со списками в python

Вот пример формата:

mylist = [('123456789'), ('987654321'), ('1234554321'),....('9999999999')] 
mylist[0] = ('123456789') 

Формат должен быть гарантировать, что они введены правильно.

Я хочу, чтобы убедиться, что она защищена от инъекции SQL,

Я знаю, что это работает:

database = connection.cursor() 
for data in mylist: 
    command = " INSERT INTO my_table(my_value) VALUES %s" %data 
    database.execute(command) 
connection.commit() 

Однако я не уверен, если это правильный способ предотвратить SQL инъекции

Что бы я предпочел сделать, но это не будет работать:

database = connection.cursor() 
for data in mylist: 
    command = " INSERT INTO my_table(my_value) VALUES %s" 
    database.execute(command, (data)) 
connection.commit() 

Ошибка I получаете:

'str' object is not callable 

Я видел онлайн here, что это правильно, так почему обыкновение это работает

+2

Пожалуйста, дайте нам полный отслеживающий. Обратите внимание, что '(data)' не является кортежем, это то же самое, что и 'data', сгруппированные в круглые скобки. Используйте '(data,)', чтобы сделать его кортежем. –

+0

Опять же, вы можете также отбросить все «(...)» круглые скобки для всего, что они делают. 'mylist = [('123456789'), ('987654321'), ('1234554321'), .... ('9999999999')]' это то же самое, что 'mylist = ['123456789', '987654321', '1234554321', .... '9999999999'] '. –

ответ

1

Очень сложно понять, что вы имеете в виду. Это моя попытка:

mylist = ['123456789','987654321','1234554321','9999999999'] 
mylist = [tuple(("('{0}')".format(s),)) for s in mylist] 
records_list_template = ','.join(['%s'] * len(mylist)) 
insert_query = ''' 
    insert into t (s) values 
    {0} 
'''.format(records_list_template) 
print cursor.mogrify(insert_query, mylist) 
cursor.execute(insert_query, mylist) 
conn.commit() 

Выход:

insert into t (s) values 
('(''123456789'')'),('(''987654321'')'),('(''1234554321'')'),('(''9999999999'')') 

вставленные кортежи:

select * from t; 
     s   
---------------- 
('123456789') 
('987654321') 
('1234554321') 
('9999999999') 
+0

Это хороший ответ, и он дает мне ту же ошибку, что и решение @Martijn Pieters. Его формат значения, попадающего в базу данных, является проблемой. Я хочу дать ему ('123456789') точно, но при преобразовании списка в кортежи я получаю синтаксическую ошибку, и данные теперь выглядят как '(' '123456789' ')' Это две одинарные кавычки внутри скобок – johnfk3

+0

@ johnfk3 Check обновление –

+0

Хорошо, я вижу, как это работает, и это прекрасно, если значения являются строками, но моя таблица и значения являются cidr-типом. Единственный способ, которым я могу вставить их в свою таблицу, - в формате '('my_cidr_value')', а не так, как вы описали с помощью ''(' 'my_cidr_value' ')'. Это моя проблема – johnfk3

3

Вам нужно пройти в кортеже:

database.execute(command, (data,)) 

Примечание запятая! Вы также можете передать список:

database.execute(command, [data]) 

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

with connection: 
    with connection.cursor() as cursor: 
     command = "INSERT INTO my_table(my_value) VALUES %s" 
     cursor.executemany(command, ((data,) for data in mylist)) 

Обратите внимание, что вы можете использовать как соединение, так и курсор в качестве менеджеров контекста. Когда блок with для соединения завершается, транзакция автоматически совершается для вас, если только не произошло исключение, и в этот момент транзакция откатывается обратно. Менеджер контекста cursor закрывает курсор, освобождая ресурсы, связанные с курсором. См. psycopg2 documentation.

+0

Формат данных - это взять мой список и добавить "" "(" "" "перед элементом и" "" ")" "" после и добавить и добавить в список, т. Е.(«данные»), и это будет правильным для вставки базы данных tot he. в вашей команде executemany данные вводятся как "" "'(' 'data' ')'" "" [оба одинарные кавычки внутри скобок]. Как получить его в правильном формате – johnfk3

+0

Это будет работать, только если 'data' является' tuple'. Проверьте, почему в [моем ответе] (http://stackoverflow.com/a/30985541/131874) –

+0

@ johnfk3: вы говорите, что ваши элементы - это уже последовательности? Можете ли вы обновить свой вопрос, чтобы показать образец того, что содержит «mylist»? –

Смежные вопросы