我希望使用C#和python客户端将GUID存储在我的SQLite数据库中。
创建数据库并插入一行,将GUID存储为字符串:
conn = sqlite3.connect(filename)
c = conn.cursor()
# Create the table. Yes, I know GUID isn't a real SQLite datatype.
c.execute('CREATE TABLE test (guid GUID PRIMARY KEY, name text)')
u = uuid.uuid4()
print u
t = (str(u), 'foo')
c.execute('INSERT INTO test VALUES (?,?)', t)
conn.commit()
conn.close()
撷取:
# ...
c.execute('SELECT * FROM test WHERE guid = "c1332103-6031-4ff7-b610-f8f3b940fa66"')
print c.fetchone()
这一切都很完美。使用UUID的默认Python __str__
表示效果很好。
C:\Users\Jonathon>makedb.py test.db
c1332103-6031-4ff7-b610-f8f3b940fa66
C:\Users\Jonathon>opendb.py test.db
(u'c1332103-6031-4ff7-b610-f8f3b940fa66', u'foo')
我怀疑使用SQLite Expert。似乎SQLite Expert对我的GUID数据类型声明感到满意:
但是,如果我编辑一行:
似乎它改变了数据类型!我之前的SELECT
会产生None
,如果我SELECT *
,我发现它不再是一个简单的unicode字符串:
C:\Users\Jonathon>opendb.py test.db
(<read-write buffer ptr 0x02239520, size 16 at 0x02239500>, u'foo')
查看磁盘上的数据,您可以看到在SQLite专家触摸后,GUID以二进制形式存储:
之前 - GUID是ASCII文本:
之后 - 以前的数据是垃圾,并且存在GUID的二进制版本:
那么在SQLite中存储GUID的“正确”方法是什么,特别是使用Python?之后,我将使用C#代码与之交互,并希望确保我以“正确”的方式处理事情。
答案 0 :(得分:7)
基本上可以在Python中为sqlite3添加对GUID数据类型的支持。您可以注册转换功能:
register_converter()
:将SQLite类型转换为Python类型register_adapter()
:将Python类型转换为SQLite类型要使用这些,您需要为connect()
的detect_types
参数传递参数。
示例:
import sqlite3
import uuid
sqlite3.register_converter('GUID', lambda b: uuid.UUID(bytes_le=b))
sqlite3.register_adapter(uuid.UUID, lambda u: buffer(u.bytes_le))
conn = sqlite3.connect('test.db', detect_types=sqlite3.PARSE_DECLTYPES)
c = conn.cursor()
c.execute('CREATE TABLE test (guid GUID PRIMARY KEY, name TEXT)')
data = (uuid.uuid4(), 'foo')
print 'Input Data:', data
c.execute('INSERT INTO test VALUES (?,?)', data)
c.execute('SELECT * FROM test')
print 'Result Data:', c.fetchone()
输出:
Input Data: (UUID('59cc2646-8666-4fb3-9f57-fe76e22603c0'), 'foo')
Result Data: (UUID('59cc2646-8666-4fb3-9f57-fe76e22603c0'), u'foo')
结果:
uuid.UUID
个对象直接传递给execute()
。适配器lambda u: buffer(u.bytes)
告诉sqlite3如何将这些转换为buffer
(在SQLite中转换为X'ABCD....'
blob。fectchone()
直接返回uuid.UUID
个对象。转换器lambda u: buffer(u.bytes)
告诉sqlite3在遇到声明类型GUID
时如何从字节数组创建它们。答案 1 :(得分:4)
您的GUID是一个字符串。将其声明为VARCHAR或CHAR,它将正确地获取文本关联。由于GUID不是类型,因此字段没有类型关联,因此数据类型为NONE。
这里描述:http://www.sqlite.org/datatype3.html
还有一个简短的讨论,有人试图在他们的支持论坛上使用SQLite Expert中的Guid:http://sqliteexpert.com/forum/YaBB.pl?num=1368018774/0
支持讨论映射系统以及如何更改映射,以及默认使用Blob的工具。