Найти - Пользователи
Полная версия: Массовый update
Начало » Python для новичков » Массовый update
1 2 3
4kpt_III
neitro
1. Не увидел здесь алхимию хотя смотрел в оба глаза.
2. Почему-бы перед тем, как обновить не проверить: а изменилось ли вообще поле?
3. Ну и индескы. Хотя об этом уже сказали. И не раз.
4. Sqlite хорош для малого хранения данных. Для чего-то сложнее нужно выбирать между PostgreSQL и Mongo (зависит от структуры данных). Учитывая Ваши данные предпочтительнее PostgreSQL.

P.S. Насчет 10кк реально не заметил. Но учитывая, что мной обновляемая БД структурно сложнее в разы и там огромное количество сложных проверок, то все равно у Вас очень много. Когда-то делал так-же без проверки. Разница была на проверяемой БД 25 и 7 сек. Так что имеет смысл все же проверить поле на изменение.
FishHook
А какие данные у вас в файле? Точно их нельзя вычислить и базу одним запросом проапдейтить?
PooH
neitro
    sql += str_update_ip_domain(arr[0], arr[1], arr[2]) 
    if i % 1000  == 0: 
	try:    # обработка исключения
	    cur.executescript(sql) # Выполняем SQL-запрос
	    sql = ''
	except sqlite.DatabaseError, err:
	    print u"Ошибка:", err
Ужас какой! Тут не весь код, но если я правильно понимаю, вы собираете в текстовой переменной текст 1000 sql-запросов и кормите этим базу? Собирайте данные в списке кортежей, а потом запускайте c executemany и биндингом параметров
neitro
Rodegast
Индекс сделал?
Нет, на тот момент не делал - сейчас этим вопросом озадачился

4kpt_III
1. Не увидел здесь алхимию хотя смотрел в оба глаза.
2. Почему-бы перед тем, как обновить не проверить: а изменилось ли вообще поле?
3. Ну и индескы. Хотя об этом уже сказали. И не раз.
4. Sqlite хорош для малого хранения данных. Для чего-то сложнее нужно выбирать между PostgreSQL и Mongo (зависит от структуры данных). Учитывая Ваши данные предпочтительнее PostgreSQL.

она была до sqlite3
Т.е. вместо куска

	try:    # обработка исключения
	    cur.executescript(sql) # Выполняем SQL-запрос
	    sql = ''
	except sqlite.DatabaseError, err:
	    print u"Ошибка:", err

была строчка вида
	try:    # обработка исключения
	    session.query(Info).filter_by(name="%s" % value).update({'text1': text1})
	except:
	    print u"Ошибка:"

Особой разницы в скорости не заметил.

PooH
Ужас какой! Тут не весь код, но если я правильно понимаю, вы собираете в текстовой переменной текст 1000 sql-запросов и кормите этим базу? Собирайте данные в списке кортежей, а потом запускайте c executemany и биндингом параметров
Именно так я и делаю, как это не было прискорбно (про 1к UPDATE).
Второе предложение не понял - пошел гуглить инфу что это и с чем едят

FishHook
А какие данные у вас в файле? Точно их нельзя вычислить и базу одним запросом проапдейтить?

Ну у меня есть данные (грубо говоря):
name|text1|date1
их 10к штук

в базе инфа храниться в виде.
id|name|date1|date2|date3|text1|text2|text3|integer
по name нужно проапдейтить бд. Я не знаю как можно 1-м запросом это сделать. По крайней мере пока.

PS Для того что бы понять необходимость обновления нужно получить эти данные. И тут тоже стоит вопрос, как это сделать. Адскую конструкцию типа
Select (name,text1,date1) from table where name = ‘value1’ or name = ‘value2’ or … name = ‘value10000’
Но это кажется совсем не красивой конструкцией.

PPS Про индексы можете пока не говорить - вопрос изучаю)))) Как использую - расскажу о результатах
PooH
neitro
Второе предложение не понял - пошел гуглить инфу что это и с чем едят
sql = '''UPDATE domains 
    SET text1 = ?, date1 = ?
    WHERE name = ?;
'''
дальше как раньше идете по файлу, но собираете свои данные в массив вида:
data = [('text1', date1, 'name'), ('text1', date1, 'name'), ('text1', date1, 'name'), ... ]
как набрали тысячу, или сколько желаете
cur.executemany(sql, data)
уйдут расходы времени на парсинг запросов, мне кажется они велики. Ну и транзакция будет фиксироваться один раз на тысячу вставок.

Ну и индекс конечно по name, вы же по нему все время ищите.
FishHook
Вообще странная программа, которая сначала накапливает данные в текстовом файле, а потом этими данными апдейтит БД. Сразу нельзя что ли?
FishHook
neitro
Я не знаю как можно 1-м запросом это сделать.
Вопрос был конкретно такой
Точно их нельзя вычислить?
поясню, если например у меня есть таблица в БД
id|date|counter1|counter2|sum
и мне нужно во всех записях увеличить дату на 1 день и counter1 на единицу и посчитать сумму counter1 и counter2, то никакой файл тут городить не нужно и все изменения можно сделать одним запросом.
FishHook
Если вам не нужна собственно сама программа, а нужен результат (если это не учебный проект, а реальная производственная необходимость), то я бы попробовал так:
1. Загружаем данные из файла в БД. Насколько я понимаю, у вас CSV файл. SQLite умеет засасывать данные из CSV.
2. собственно апдейтим используя синтаксис
UPDATE table
SET columns = (SELECT .....)
WHERE ....
neitro
FishHook
Вообще странная программа, которая сначала накапливает данные в текстовом файле, а потом этими данными апдейтит БД. Сразу нельзя что ли?

Можно, даже нужно, но в данном конкретном случае - я изучал вопрос “какой кусок кода занимает много времени” и выяснил, что конкретно этот кусок, поэтому по нему и задал вопрос.
4kpt_III
neitro
она была до sqlite3

И куда алхимия писала? В Астрал? Если Вы другие БД еще не пробовали. Сложно поверить, что после алхимии Вы перешли на чистый SQL да еще и без алхимического core. Короче, алхимией тут и не пахло.

neitro
PS Для того что бы понять необходимость обновления нужно получить эти данные. И тут тоже стоит вопрос, как это сделать. Адскую конструкцию типа
Select (name,text1,date1) from table where name = ‘value1’ or name = ‘value2’ or … name = ‘value10000’
Но это кажется совсем не красивой конструкцией.

Получать порциями и обновлять, если нужно. Для этого есть in_ в алхимии.

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