Как мне написать BLOB, любой BLOB для sqlite? - PullRequest
0 голосов
/ 15 мая 2019

Мне нужно записать объект Obj-C (например, NSString в этом случае) в базу данных sqlite и сохранить его в столбце BLOB, используя Python 2.7. В этой степени я написал этот демонстрационный код, который не работает с приведенной ниже трассировкой.

    from sqlite3 import connect
    from Foundation import NSArchiver

    conn = connect(':memory:')
    create = "CREATE TABLE test(data BLOB)"
    conn.execute(create)
    conn.commit()

    blob = NSArchiver.archivedDataWithRootObject_("Hello World").bytes()
    print type(blob), blob
    sql = "INSERT INTO test VALUES (?)"
    data = [blob]

    conn.execute(sql, data)
    conn.commit()

Это прослеживается с:

    $ ./sqlite3_test.py
    <type 'memoryview'> <memory at 0x104a5e218>
    Traceback (most recent call last):
      File "./sqlite3_test.py", line 16, in <module>
        conn.execute(sql, data)
    sqlite3.InterfaceError: Error binding parameter 0 - probably unsupported type.

Никакое количество магии, использующей sqlite3.Binary (которое определяется как Binary = buffer внутри модуля sqlite3) или .tobytes() (из memoryview ), не улучшило эту работу.

Я также пытался создать объект buffer () из BLOB-объекта NSArchiver, но наивный подход:

b = buffer(blob, 0, len(blob))

восходит к TypeError: buffer object expected - возможно, объекты NSArchiver не являются строками Python.

1 Ответ

0 голосов
/ 15 мая 2019

У меня есть рабочий пример! При вызове Objective-C bytes() мне нужно вызвать просмотр памяти .tobytes(), который затем можно сериализовать в buffer().

#!/usr/bin/python -tt

from sqlite3 import connect, Binary
from Foundation import NSArchiver

conn = connect(':memory:')
create = "CREATE TABLE test(data BLOB)"
conn.execute(create)
conn.commit()

str = NSString.alloc().initWithString_("Hello World")
blob = NSArchiver.archivedDataWithRootObject_(str).bytes().tobytes()
print "Original (%s): %s" % (len(blob), blob)
sql = "INSERT INTO test VALUES (?)"
data = [Binary(blob)]

conn.execute(sql, data)
conn.commit()

cursor = conn.cursor()
cursor.execute("SELECT * FROM test")
rows = cursor.fetchall()
for r in rows:
    print "In database (%s): %s" % (len(r[0]), r[0])

Это дает:

$ ./sqlite3_test.py 
Original (84):
   streamtyped???@???OC_PythonString?NSString?NSObject??i?+
                                                                Hello World?
In database (84):
   streamtyped???@???OC_PythonString?NSString?NSObject??i?+
                                                                Hello World?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...