【问题标题】:How to partially overwrite blob in an sqlite3 db in python via SQLAlchemy?如何通过 SQLAlchemy 在 python 中的 sqlite3 db 中部分覆盖 blob?
【发布时间】:2021-03-22 07:07:03
【问题描述】:

我有一个包含二进制表示的 blob 列的数据库,如下所示

我感兴趣的值在标记中被编码为 little endian unsigned long long (8 字节) 值。像这样读取这个值可以正常工作

p = session.query(Properties).filter((Properties.object_id==1817012) & (Properties.name.like("%OwnerUniqueID"))).one()
id = unpack("<Q", p.value[-8:])[0]

上面例子中的id是1657266。 现在我想做的是相反的。我有行对象 p,我有一个十进制格式的数字(出于测试目的使用相同的 1657266),我想以小端格式将该数字写入相同的 8 个字节。 我一直在尝试通过 SQL 语句这样做

UPDATE properties SET value = (SELECT substr(value, 1, length(value)-8) || x'b249190000000000' FROM properties WHERE object_id=1817012 AND name LIKE '%OwnerUniqueID%') WHERE object_id=1817012 AND name LIKE '%OwnerUniqueID%'

但是当我这样做时,我就无法再阅读它了。至少不使用 SQLAlchemy。当我尝试与上面相同的代码时,我收到错误消息Could not decode to UTF-8 column 'properties_value' with text '☻',所以看起来它是以不同的格式编写的。 有趣的是,在 DB Browser 中使用普通的 select 语句仍然可以正常工作,并且 blob 仍然与上面的屏幕截图完全相同。 现在理想情况下,我希望能够使用 SQLAlchemy ORM 仅写入这 8 个字节,但如果需要的话,我会满足于原始 SQL 语句。

【问题讨论】:

    标签: python sqlalchemy blob


    【解决方案1】:

    通过基本上颠倒我过去阅读它的过程,我设法让它与 SQLAlchemy 一起工作。事后看来,使用 + 连接和 [:-8] 分割正确的部分似乎很明显。

    p = session.query(Properties).filter((Properties.object_id==1817012) & (Properties.name.like("%OwnerUniqueID"))).one()
    p.value = p.value[:-8] + pack("<Q", 1657266)
    

    通过为 SQLAlchemy 打开 ECHO,我得到了以下原始 SQL 语句:

    UPDATE properties SET value=? WHERE properties.object_id = ? AND properties.name = ?
    (<memory at 0x000001B93A266A00>, 1817012, 'BP_ThrallComponent_C.OwnerUniqueID')
    

    我想如果你想手动做同样的事情,这不是特别有用。

    值得注意的是,我的问题中的原始 SQL 语句不仅适用于使用 DB 浏览器读取它,而且适用于使用相关数据库的游戏客户端。似乎只有 SQLAlchemy 有问题,试图将其解码为 UTF-8 似乎。

    【讨论】:

      猜你喜欢
      • 2022-01-27
      • 2011-11-27
      • 2015-03-29
      • 2020-07-22
      • 2021-12-12
      • 2021-06-26
      • 2011-03-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多