不能在 sqlite3 blob 字段上使用 pony orm

can't use pony orm on sqlite3 blob fields

只是尝试使用 pony ORM(和 python3.5,sqlite3)进行一些基本练习。 我只想打印 select 查询我拥有的一些数据,而无需进一步处理。 Pony orm 好像一点都不喜欢....

sqlite 数据库转储

PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE sums (t text, path BLOB, name BLOB, sum text, primary key (path,name));
INSERT INTO "sums" VALUES('directory','','','');
INSERT INTO "sums" VALUES('file','','sums-backup-f.db','6859b35f9f026317c5df48932f9f2a91');
INSERT INTO "sums" VALUES('file','','md5-tree.py','c7af81d4aad9d00e88db7af950c264c2');
INSERT INTO "sums" VALUES('file','','test.db','a403e9b46e54d6ece851881a895b1953');
INSERT INTO "sums" VALUES('file','','sirius-alexa.db','22a20434cec550a83c675acd849002fa');
INSERT INTO "sums" VALUES('file','','sums-reseau-y.db','1021614f692b5d7bdeef2a45b6b1af5b');
INSERT INTO "sums" VALUES('file','','.md5-tree.py.swp','1c3c195b679e99ef18b3d46044f6e6c5');
INSERT INTO "sums" VALUES('file','','compare-md5.py','cfb4a5b3c7c4e62346aa5e1affef210a');
INSERT INTO "sums" VALUES('file','','charles.local.db','9c50689e8185e5a79fd9077c14636405');
COMMIT;

这是我在 python3.5 上尝试 运行 的代码 shell:

from pony.orm import *
db = Database()
class File(db.Entity) :
    _table_ = 'sums'
    t = Required(str)
    path = Required(bytes)
    name = Required(bytes)
    sum = Required(str)
    PrimaryKey(path,name)
db.bind('sqlite','/some/edited/path/test.db')
db.generate_mapping()

File.select().show()

它像这样失败了:

Traceback (most recent call last):
  File "/usr/lib/python3.5/site-packages/pony/orm/core.py", line 5149, in _fetch
    try: result = cache.query_results[query_key]
KeyError: (('f', 0, ()), (<pony.orm.ormtypes.SetType object at 0x7fd2d2701708>,), False, None, None, None, False, False, False, ())

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 2, in show
  File "/usr/lib/python3.5/site-packages/pony/utils/utils.py", line 75, in cut_traceback
    raise exc  # Set "pony.options.CUT_TRACEBACK = False" to see full traceback
  File "/usr/lib/python3.5/site-packages/pony/utils/utils.py", line 60, in cut_traceback
    try: return func(*args, **kwargs)
  File "/usr/lib/python3.5/site-packages/pony/orm/core.py", line 5256, in show
    query._fetch().show(width)
  File "/usr/lib/python3.5/site-packages/pony/orm/core.py", line 5155, in _fetch
    used_attrs=translator.get_used_attrs())
  File "/usr/lib/python3.5/site-packages/pony/orm/core.py", line 3859, in _fetch_objects
    real_entity_subclass, pkval, avdict = entity._parse_row_(row, attr_offsets)
  File "/usr/lib/python3.5/site-packages/pony/orm/core.py", line 3889, in _parse_row_
    avdict[attr] = attr.parse_value(row, offsets)
  File "/usr/lib/python3.5/site-packages/pony/orm/core.py", line 1922, in parse_value
    val = attr.validate(row[offset], None, attr.entity, from_db=True)
  File "/usr/lib/python3.5/site-packages/pony/orm/core.py", line 2218, in validate
    val = Attribute.validate(attr, val, obj, entity, from_db)
  File "/usr/lib/python3.5/site-packages/pony/orm/core.py", line 1894, in validate
    if from_db: return converter.sql2py(val)
  File "/usr/lib/python3.5/site-packages/pony/orm/dbapiprovider.py", line 619, in sql2py
    if not isinstance(val, buffer): val = buffer(val)
TypeError: string argument without an encoding

我是不是用错了,或者这是一个错误?我不介意提交错误,但这是我第一次使用这个 orm,所以我认为先检查一下可能会更好...

SQLite 有一个(错误的)特性,它允许列存储任意值而不管列类型。每个 SQLite 列都具有亲和力,而不是严格的数据类型,而每个值都有一个存储 class,在同一列中可以不同。例如,您可以将文本值存储在整数列中,反之亦然。有关详细信息,请参阅 Datatypes In SQLite Version 3

错误的原因是 table 在其 BLOB 列中包含 "wrong" 类型的值。更正 SQLite 二进制文字 looks,如 x'abcdef'。您使用的 INSERT 命令改为插入 UTF8 字符串。

这个问题在 latest version of Pony 中得到了一定程度的修复,您可以从 GitHub 中获取。现在,如果 Pony 从 BLOB 列接收到一个字符串值,它只会保留该值而不会抛出异常。

如果您使用 Pony 填充 table,它会将 BLOB 数据写入正确的二进制值,因此稍后可以毫无问题地读取它们。