2016-04-10 4 views
0

Я знаю, что это было затронуто несколько раз, но я не могу заставить это работать. Я пишу программу python, которая возьмет файл дампа базы данных sqlite3, проанализирует его и заново создаст его с помощью средства миграции базы данных (так называемые yoyo-migrations).python + sqlite3 - Не удается получить данные о блобе для работы

Я столкнулся с проблемой с данными blob в sqlite3 и как правильно отформатируйте его.

Вот основные объяснение моих программ выполнения - читать в файле дампа, разделиться на CREATE заявления, заявления INSERT и другие - генерировать файлы миграции для СОЗДАЕТ - генерировать файл миграции для каждого из таблиц вставляет - запустить миграция для восстановления базы данных (кроме того, она теперь построена из миграций)

В основном мне была предоставлена ​​база данных, и мне нужно было контролировать ее с помощью миграции. Это только первый шаг (получение вещи перестроены с помощью инструмента миграции)

Вот создание таблицы таблицы двоичных объектов:

CREATE TABLE blob_table(
    blockid INTEGER PRIMARY KEY, 
    block blob 
) 

Я затем создать файл миграции:

# 
# file: migrations/0001.create_table.py 
# Migration to build tables (autogenerated by parse_dump.py) 
# 

from yoyo import step 
step('CREATE TABLE blob_table(blockid INTEGER PRIMARY KEY, block blob);') 

Обратите внимание, что я просто пишу это в файл, а затем в конце запуска миграции. Затем мне нужно изменить миграцию «семян», которая вставляет данные. Здесь я столкнулся с бедой!

# here is an example insert line from the dump 
INSERT INTO blob_table VALUES(765,X'00063030F180800FE1C'); 

Так материал Х 'представляет данные BLOB, и мне нужно написать файл питона, который вставит данные обратно в таблицу. У меня большой объем данных, поэтому я использую синтаксис execute execute. Вот что файл миграция семян выглядит как (пример):

# 
# file: migrations/0011.seed_blob_table.py 
# Insert seed data for blob table 
# 

from yoyo import step 
import sqlite3 

def do_step(conn): 
    rows = [ 
     (765,sqlite3.Binary('00063030303031340494100')), 
     (766,sqlite3.Binary('00063030303331341FC5150')), 
     (767,sqlite3.Binary('00063030303838381FC0210')) 
    ] 
    cursor = conn.cursor() 
    cursor.executemany('INSERT INTO blob_table VALUES (?,?)', rows) 

# run the insert 
step(do_step) 

Я попытался с помощью sqlite3.Binary(), питон встроенного buffer() обе комбинации два, а также int('string', base=16), hex() и многих других. Независимо от того, что я делаю, он не будет соответствовать базе данных с дампа. То, что я имею в виду:

Если я открываю новую и старую сторону базы данных по стороне и преобразования приложений этот запрос:

# in the new database, it comes out as a string 
SELECT * FROM blob_table WHERE blockid=765; 
> 765|00063030303031340494100 

# in the old database, it displays nothing 
SELECT * FROM blob_table WHERE blockid=765; 
> 765| 

# if I do this in the old one, I get the x'' from the dump 
SELECT blockid, quote(block) FROM blob_table WHERE blockid=765; 
765|X'00063030303031340494100' 

# if I use the quote() in the new database i get something different 
SELECT blockid, quote(block) FROM blob_table WHERE blockid=765; 
765|X'303030363330333033303330... (truncated, this is longer than the original and only has digits 0-9 

Моя конечная цель заключается в восстановлении базы данных и он будет идентичен начиная один (из которого была сделана свалка). Любые советы по получению материала blob очень ценятся!

ответ

1

Класс buffer способен обрабатывать двоичные данные. Тем не менее, он заботится о сохранении данных, которые вы ему даете, а '00063030303031340494100' не является двоичными данными; это строка, содержащая цифры ноль, ноль, ноль, шесть и т.д.

построить строку, содержащую двоичные данные, используйте decode:

import codecs 
blob = buffer(codecs.decode(b'00063030303031340494100', 'hex_codec')) 
+0

прекрасно работает. Спасибо огромное! – mbiokyle

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