Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 6, 2019 14:57:34

r4khic
Зарегистрирован: 2019-07-23
Сообщения: 68
Репутация: +  0  -
Профиль   Отправить e-mail  

Как сделать условие на insert?

Всем привет.Я пытаюсь сделать множественный 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)

Офлайн

#2 Окт. 6, 2019 17:07:02

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10024
Репутация: +  857  -
Профиль   Отправить e-mail  

Как сделать условие на insert?

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.
Даже если ты парсишь много ресурсов, это не значит, что их надо сваливать в одну кучу и потом выполнять одну большую команду. Нужно подготовить данные, в том числе и профильтровать их, и только потом, отфильтрованные, их можно писать в базу данных специальным методом, выполняющим множество команд за один раз.



Офлайн

#3 Окт. 7, 2019 06:35:48

r4khic
Зарегистрирован: 2019-07-23
Сообщения: 68
Репутация: +  0  -
Профиль   Отправить e-mail  

Как сделать условие на insert?

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
Даже если ты парсишь много ресурсов, это не значит, что их надо сваливать в одну кучу и потом выполнять одну большую команду. Нужно подготовить данные, в том числе и профильтровать их, и только потом, отфильтрованные, их можно писать в базу данных специальным методом, выполняющим множество команд за один раз.
Ну я не говорил что у меня данные не подготовленные и не отфильтрованные данные.Наоборот у меня данные все подготовлены.

Офлайн

#4 Окт. 7, 2019 09:02:41

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10024
Репутация: +  857  -
Профиль   Отправить e-mail  

Как сделать условие на insert?

Вот пример с записью нескольких строк

Для 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() эту строку запроса и кортеж/список из этих ста кортежей. Это и есть подготовка. В методе записи данных в БД не должно быть никаких условий проверки на сто кортежей. Эти сто кортежей должны быть подготовлены снаружи метода и поданы в него, а от него требуется только их записать, подключившись к базе данных.



Офлайн

#5 Окт. 7, 2019 09:12:57

r4khic
Зарегистрирован: 2019-07-23
Сообщения: 68
Репутация: +  0  -
Профиль   Отправить e-mail  

Как сделать условие на insert?

py.user.next
Так что ты должен сделать сто кортежей и одну строку запроса. Затем один раз подать в execute_many() эту строку запроса и кортеж/список из этих ста кортежей. Это и есть подготовка. В методе записи данных в БД не должно быть никаких условий проверки на сто кортежей. Эти сто кортежей должны быть подготовлены снаружи метода и поданы в него, а от него требуется только их записать, подключившись к базе данных.
Понял ! Благодарю

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version