在sqlite中存储GUID的正确方法

Jon*_*art 7 python sqlite

我希望使用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()
Run Code Online (Sandbox Code Playgroud)

取:

# ...
c.execute('SELECT * FROM test WHERE guid = "c1332103-6031-4ff7-b610-f8f3b940fa66"')
print c.fetchone()
Run Code Online (Sandbox Code Playgroud)

一切都很完美.使用__str__UUID 的默认Python 表示效果很好.

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')
Run Code Online (Sandbox Code Playgroud)

我怀疑使用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')
Run Code Online (Sandbox Code Playgroud)

查看磁盘上的数据,您可以看到在SQLite专家触摸后,GUID以二进制形式存储:

之前 - GUID是ASCII文本:

在此输入图像描述

之后 - 以前的数据是垃圾,并且存在GUID的二进制版本:

在此输入图像描述


那么在SQLite中存储GUID 的"正确"方法是什么,特别是使用Python?之后,我将使用C#代码与之交互,并希望确保我以"正确"的方式处理事情.

Jon*_*art 8

实际上,可以在Python中为sqlite3添加对GUID数据类型的支持.您可以注册转换功能:

要使用这些,您需要传递参数的detect_types参数connect().

例:

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()
Run Code Online (Sandbox Code Playgroud)

输出:

Input Data: (UUID('59cc2646-8666-4fb3-9f57-fe76e22603c0'), 'foo')
Result Data: (UUID('59cc2646-8666-4fb3-9f57-fe76e22603c0'), u'foo')
Run Code Online (Sandbox Code Playgroud)

结果:

  • uuid.UUID直接传递对象execute().适配器lambda u: buffer(u.bytes)告诉sqlite3如何将它们转换为a buffer(转换为X'ABCD....'SQLite中的blob).
  • fectchone() is returning uuid.UUID objects directly. The converter lambda u: buffer(u.bytes) tells sqlite3 how to create those from a byte array when it encounters a declared type of GUID.
  • These GUIDs are being stored as 16-byte binary blobs, in little-endian order.
  • I can successfully open/edit the databases using SQLite Expert (in its default configuration).


gvi*_*iew 5

您的GUID是一个字符串。将其声明为VARCHAR或CHAR,它将正确拾取文本相似性。由于GUID不是类型,因此该字段没有类型相似性,因此将具有NONE数据类型。

此处对此进行了描述:http : //www.sqlite.org/datatype3.html

在他们的支持论坛上,也有关于在SQLite Expert中使用Guid的人的简短讨论:http ://sqliteexpert.com/forum/YaBB.pl?num=1368018774/0

支持人员讨论了映射系统以及如何更改映射,以及默认使用Blob的工具。