В Python sqlite3 я должен использовать sleep () после любой операции SQL и commit ()? - PullRequest
1 голос
/ 16 октября 2011

Я делал некоторые скриптовые обновления для базы данных sqlite медиаплеера Clementine (60 000 записей) и обнаружил, что в итоге база данных была повреждена.

Поэтому я сильно подозревал, что мои операции записи вцикл for не успел завершиться до начала следующего цикла.Я протестировал time.sleep () в течение 2 секунд после моего вызова UPDATE и 15 секунд после моего периодического коммита ().Кажется, это работает, но весь процесс стал очень медленным.Пример кода:

CommitInterval = 1000
artistCounter = 0
for artist in allArtists
    artistCounter += 1

    for record in albumRatings:
        album = record[0]
        rating = record[1]

        dbCursor.execute('UPDATE songs SET rating = ? WHERE LOWER(songs.artist) == ? AND   LOWER(songs.album) == ? AND rating < ?', (rating, artist, album, rating))

        # short sleep
        ShortSleepSec = 2
        time.sleep(ShortSleepSec)

    if artistCounter == CommitInterval:
        db.commit()
        artistCounter = 0

        # long sleep
        SleepSec = 15
        print 'Sleep %d seconds...' % (SleepSec)
        time.sleep(SleepSec)

Вот мои вопросы: Должен ли я действительно спать после UPDATE и commit () или только одного из них?Как рассчитать, сколько я должен спать после этих звонков?

Большое спасибо!

Ответы [ 2 ]

2 голосов
/ 16 октября 2011

Sqlite не нужно спать после коммита.Sqlite является синхронным, внутрипроцессным, поэтому к моменту возврата commit () операция будет завершена.Но: использование sqlite может быть опасным для нескольких потоков.

0 голосов
/ 27 марта 2016

Может быть немного поздно, но

  • вам не нужно sleep между операциями с базой данных
  • вы не должны вставлять отдельные записи снова и снова

Модуль sqlite3 предоставляет вам cursor.executemany(). Это сильно сократит время выполнения . Используйте это так:

par = [ (row[1], artist, row[0], row[1]) for row in albumRatings ]
sql = 'UPDATE songs SET rating = ? WHERE LOWER(songs.artist) == ? AND   LOWER(songs.album) == ? AND rating < ?'
dbCursor.executemany(sql, par)

Я бы db.commit() сразу после этого раунда.

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

...