我需要使用Python 2.7将Obj-C对象(在这种情况下为NSString)写入sqlite数据库并将其存储在BLOB列中。 在这种程度上,我编写了此演示代码,但失败,并没有下面的回溯。
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
(在sqlite3模块中定义为Binary = buffer
)或.tobytes()
(来自memoryview)的魔术师都无法使效果更好。
我还尝试从NSArchiver Blob中创建一个buffer()对象,但是很简单:
b = buffer(blob, 0, len(blob))
使用TypeError: buffer object expected
进行追溯-可以说NSArchiver对象不是Python字符串。
答案 0 :(得分:0)
我有一个可行的例子!
在Objective-C调用bytes()
上,我需要调用memoryview .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?