Найти - Пользователи
Полная версия: Как сделать условие на insert?
Начало » Python для новичков » Как сделать условие на insert?
1
r4khic
Всем привет.Я пытаюсь сделать множественный insert.Чтобы сделать это.
У меня есть переменная sql и она содержит в себе такой запрос:
 sql = '''INSERT INTO items (res_id, log_id, link, title, content, n_date, nd_date, s_date, not_date)'''
И есть переменная values:
 values = ''' VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ''' % (
                                res_id,
                                log_id,
                                resource_link,
                                item_title,
                                item_content,
                                n_date,
                                nd_date,
                                s_date,
                                not_date)
В итоге происходит конкатенация:result = sql + values
И переменная result содержит в себе такой sql запрос:
 INSERT INTO items (res_id, log_id, link, title, content, n_date, nd_date, s_date, not_date) VALUES ('35', '1', 'http://bryansk-news.net/society/2019/10/05/37343.html', 'Сегодня брянских водителей проверят на алкоголь', 'Сегодня брянских водителей проверят на алкоголь
Сегодня, 07:14
5 октября ждать нетрезвых автомобилистов будут в районе д. 1 по проспекту Московскому в Фокинском районе.
Останавливать транспортные средства будут с 23 часов 25 минут в течение получаса.
Если вы стали свидетелем нарушений ПДД, сообщите об этом ближайшему наряду ДПС или в дежурную часть по телефону 74-71-02.
Источник: https://news.nashbryansk.ru
', 'Added by Raha', '1570227276', '1570255714.6161082', '2019-10-05')
Вот вызов метода execute:
 huge_insert = parser.huge_insert_db(result)
Вот сам метод:
 def huge_insert_db(self, result):
        self.cursor.execute(result)
        print('Запись 100 новостей успешно произведена!')
Я парсю около 50 ресурсов,и я не знаю как сделать проверку.То есть проверку если в переменной result набралось 100 ссылок.То тогда производим множественный insert.
Я пытался сделать так,но это не работает:
 result_list = []
                            sql = '''INSERT INTO items (res_id, log_id, link, title, content, n_date, nd_date, s_date, not_date)'''
                            values = ''' VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ''' % (
                                res_id,
                                log_id,
                                resource_link,
                                item_title,
                                item_content,
                                n_date,
                                nd_date,
                                s_date,
                                not_date)
                            result = sql + values
                            result_list.append(result)
                            if len(result_list) == 100:
                                huge_insert = parser.huge_insert_db(result)
py.user.next
r4khic
И есть переменная values:
  
values = ''' VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ''' % (
                                res_id,
                                log_id,
                                resource_link,
                                item_title,
                                item_content,
                                n_date,
                                nd_date,
                                s_date,
                                not_date)
Так нельзя делать, так как это можно использовать для инъекций. Нужно использовать защищённые поля.

r4khic
Вот сам метод:
  
self.cursor.execute(result)
Для таких вещей есть execute_many() обычно. То есть тебе надо где-то составить кортеж запросов, а потом передать его в многокомандный метод.

r4khic
Я парсю около 50 ресурсов,и я не знаю как сделать проверку.То есть проверку если в переменной result набралось 100 ссылок.То тогда производим множественный insert.
Даже если ты парсишь много ресурсов, это не значит, что их надо сваливать в одну кучу и потом выполнять одну большую команду. Нужно подготовить данные, в том числе и профильтровать их, и только потом, отфильтрованные, их можно писать в базу данных специальным методом, выполняющим множество команд за один раз.
r4khic
py.user.next
Так нельзя делать, так как это можно использовать для инъекций. Нужно использовать защищённые поля.
Окей.Я вас понял.Вот так изменил запрос.
 sql = '''INSERT INTO items res_id, log_id, link, title, content, n_date, nd_date, s_date, not_date VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')''',(
                         res_id,
                         log_id,
                         str(resource_link),
                         str(item_title),
                         str(item_content),
                         str(n_date),
                         nd_date,
                         s_date,
                         not_date
                                    )
py.user.next
Для таких вещей есть execute_many() обычно. То есть тебе надо где-то составить кортеж запросов, а потом передать его в многокомандный метод.
Я в курсе,но мне надо именно пока что без execute_many()
py.user.next
Даже если ты парсишь много ресурсов, это не значит, что их надо сваливать в одну кучу и потом выполнять одну большую команду. Нужно подготовить данные, в том числе и профильтровать их, и только потом, отфильтрованные, их можно писать в базу данных специальным методом, выполняющим множество команд за один раз.
Ну я не говорил что у меня данные не подготовленные и не отфильтрованные данные.Наоборот у меня данные все подготовлены.
py.user.next
Вот пример с записью нескольких строк

Для MySQL
https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-executemany.html
data = [
('Jane', date(2005, 2, 12)),
('Joe', date(2006, 5, 23)),
('John', date(2010, 10, 3)),
]
stmt = "INSERT INTO employees (first_name, hire_date) VALUES (%s, %s)"
cursor.executemany(stmt, data)

Для PostgreSQL
https://zetcode.com/python/psycopg2/
cars = (
(1, 'Audi', 52642),
(2, 'Mercedes', 57127),
(3, 'Skoda', 9000),
(4, 'Volvo', 29000),
(5, 'Bentley', 350000),
(6, 'Citroen', 21000),
(7, 'Hummer', 41400),
(8, 'Volkswagen', 21600)
)

cur = con.cursor()

query = "INSERT INTO cars (id, name, price) VALUES (%s, %s, %s)"
cur.executemany(query, cars)

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

Эти плейсхолдеры - не просто удобные поля для замены. Это не аналог форматной строки, как тебе может показаться. Они отличаются от форматной строки тем, что при подстановке сначала всё проверяется на SQL-инъекцию и другие сюрпризы и только потом содержимое кортежей подставляется. Это средство безопасности.

Так что ты должен сделать сто кортежей и одну строку запроса. Затем один раз подать в execute_many() эту строку запроса и кортеж/список из этих ста кортежей. Это и есть подготовка. В методе записи данных в БД не должно быть никаких условий проверки на сто кортежей. Эти сто кортежей должны быть подготовлены снаружи метода и поданы в него, а от него требуется только их записать, подключившись к базе данных.
r4khic
py.user.next
Так что ты должен сделать сто кортежей и одну строку запроса. Затем один раз подать в execute_many() эту строку запроса и кортеж/список из этих ста кортежей. Это и есть подготовка. В методе записи данных в БД не должно быть никаких условий проверки на сто кортежей. Эти сто кортежей должны быть подготовлены снаружи метода и поданы в него, а от него требуется только их записать, подключившись к базе данных.
Понял ! Благодарю
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB