10

我正在寻找使用 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之前的 yield None,如果 I SELECT *,我看到它不再是一个简单的 unicode 字符串:

C:\Users\Jonathon>opendb.py test.db
(<read-write buffer ptr 0x02239520, size 16 at 0x02239500>, u'foo')

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

之前 - GUID 是 ASCII 文本:

在此处输入图像描述

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

在此处输入图像描述


那么在 SQLite 中存储 GUID 的“正确”方法是什么,特别是使用 Python 呢?稍后,我也会让 C# 代码与之交互,并希望确保我以“正确”的方式进行操作。

4

2 回答 2

10

基本上可以在 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()

输出:

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 如何将它们转换为 a bufferX'ABCD....'在 SQLite 中转换为 blob。
  • fectchone()直接返回uuid.UUID对象。转换器lambda u: buffer(u.bytes)告诉 sqlite3 在遇到声明的GUID.
  • 这些 GUID 被存储为 16 字节二进制 blob,以 little-endian 顺序存储。
  • 我可以使用 SQLite Expert(在其默认配置中)成功打开/编辑数据库。
于 2013-09-17T06:13:28.693 回答
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 的工具。

于 2013-09-16T06:19:51.517 回答