2010-10-13 2 views
1

Я решил, что я не люблю автоматическую регистрацию и переименование, предоставленную Mendeley, но обнаружил, что он отслеживает все в базе данных sqlite, которую я могу легко прочитать и изменить с Python.Рассмотрение затем обновление строк в sqlite с помощью Python

Мой вопрос: если я собираюсь перебирать строки таблицы с файловыми путями и хэшами, которые служат в качестве идентификаторов, которые используются в другом месте в базе данных, что является подходящим шаблоном для обновления путей когда я двигаюсь, проверьте, нужно ли переименовать файл, а затем нужно обновить строку в db при перемещении файла.

Я начал собирать некоторые Python для этого, но мне кажется, что мне, вероятно, нужно сделать запрос заранее, чтобы получить все строки, которые я собираюсь позже перебирать, а затем выполнить инструкции REPLACE или UPDATE для файлов, которые я решил переместить.

Я не знаком с внутренними компонентами модуля sqlite3, но я полагаю, что было бы плохой идеей делать REPLACE/UPDATE при повторении курсора, используемого для первоначального выбора.

Есть ли другой способ сделать это, что не требует возврата с REPLACE/UPDATE? Мне нужно делать запросы из других таблиц, используя хэш файла, чтобы получить некоторые другие метаданные, чтобы построить переименование.

ответ

2

Я не думаю, что есть способ изменить строки в таблице, кроме как через SQL - UPDATE, или INSERT ИЛИ REPLACE. (Заманчиво думать, что объект sqlite3.Row может разрешить назначение и записать обратно в строку, которую он представляет, но нет.)

Что касается UPDATE (через 2-й курсор), в то время как есть выдающийся курсор, используемый для оригинальный SELECT - вы спрашиваете, является ли это плохая идея - я не знаю, беспокоитесь ли вы о правильности или производительности (правильность: курсор запутался и не перебирает все строки, которые ему нужно ровно один раз, производительность: курсор выполняет итерацию всех строк, которые должны выполняться ровно один раз, но есть куча дорогостоящих дополнительных запросов)?

Правильность WRT, кажется, работает нормально - я просто быстро проверил, где я создал два курсора c1 и c2, затем на c1 выполнил команду SELECT, затем на c2 выполнил команду UPDATE, влияющую на те же строки, затем посмотрел на результат c1.fetchall(). Он по-прежнему содержал все правильные строки, хотя данные в первой строке были устаревшими (вероятно, с исходным запросом), а данные в последующих строках были обновлены (возможно, только с fetchall после обновления).

(Кроме того, если UPDATE на c2 влияет на то, какие записи будут возвращены SELECT на c1, такие записи больше не будут извлечены, но очевидно, что все, что уже было выбрано, уже было выбрано, и снова cursor.execute() чтобы получить первую запись сразу, поэтому, используя тот же командный порядок, что и выше, и с помощью команды UPDATE, которая сделает исходный SELECT ничего не найденным, более поздняя c1.fetchall() все еще возвращает одну запись.)

Что касается производительности, Я не знаю - из предыдущего абзаца мне кажется, что он должен повторить запрос, который может быть или не быть дорогим в зависимости от запроса. (Возможно, это не повторяется буквально, возможно, эта работа отложена до фактического получения в любом случае.)

Рассказ: я не думаю, что есть другой способ сделать это без UPDATE или REPLACE, и я думаю, что это сработает ok, чтобы делать эти UPDATE, даже если итерация на исходном курсоре.

+0

Спасибо за примечания по этому вопросу. Я больше беспокоился о правильности, чем о производительности. Я полагаю, что нужно было бы использовать более высокий уровень абстракции, такой как ORM, чтобы иметь возможность делать то, что я изначально хотел, по крайней мере, с точки зрения кода Python.В конце концов, я заметил, по крайней мере, для Менделей, что мне фактически не нужно обновлять имена файлов в базе данных, поскольку, если один переименовывает файл, а затем просит Mendeley посмотреть папку, содержащую его, он обновит пути, когда найдет переименован файлы с тем же хешем, что и предыдущий путь к файлу. –

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