一个 Python 库,轻量的,基于 sqlite 的持久化 list, dict - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
Sailwww
V2EX    分享创造

一个 Python 库,轻量的,基于 sqlite 的持久化 list, dict

  •  
  • &nsp; Sailwww 2022-03-14 12:29:23 +08:00 3482 次点击
    这是一个创建于 1317 天前的主题,其中的信息可能已经有所发展或是发生改变。

    https://github.com/sailist/dbrecord

    前一段时间训练文本数据集,为了方便 shuffle 操作整出来的,这两天简单重构后分享一下。

    主要特性:

    • 接口友好,提供 python list, dict 中大部分的(增改查)相关的操作方法
    • 基于 sqlite ,使用简单,安装即可使用,不需要任何配置,一个文件可带走
    • list 和 dict 基于相同的底层数据表,提供了尽可能兼容的互相转换操作,可以用 index 读 dict (可以看成是 OrderedDict ),也可以用 key 读 list ( list append 时候 key 是相应的 ns 时间戳)。
    • 轻量:不到 500 行的代码(大概有一定的学习用途)
    • 测试完善

    用途:

    • 可以用于构建配置文件
    • 存储只有 key 或者 index 检索需求的数据(比如我曾经用于构建文本训练数据)

    感兴趣可以关注一下: https://github.com/sailist/dbrecord

    14 条回复    2022-03-16 18:56:43 +08:00
    Sailwww
        1
    Sailwww  
    OP
       2022-03-14 13:31:11 +08:00
    补一条,sqlite 支持亿量级的数据低延迟索引读取,所以该库也有类似的性能表现,在一些场景下是替代 json 等数据格式的更好选择
    BingoXuan
        2
    BingoXuan  
       2022-03-14 14:07:13 +08:00
    Shazoo
        3
    Shazoo  
       2022-03-14 16:20:24 +08:00
    协程支持?多线程支持? multiprocess ?
    Sailwww
        4
    Sailwww  
    OP
       2022-03-14 18:08:18 +08:00
    @BingoXuan 还真是,才发现有这个...对比了一下,基本确实是在重复造轮子,不过还是总结一下区别
    - 在 io 上,因为我建的是双层索引,同时还有 id 自增列,所以在单值读取上慢了很多(但也在 1e-5 量级内,btw ,sqlitedict 是 1e-9 量级),数据库大小同量级下(因为索引)应该也大一些;优点是可以通过 list 的接口读取。
    - 多值上它没有提供接口,在同时读取多个 key 或者 index 的场景下,我比他快 10 倍以上
    - 整体上这个库算是一个 sqlite 小玩具,里面还提供了一个二分求数据库大小的函数,在无自增 id 缺失的情况下,比 select count(*) 要快 1000 倍左右
    Sailwww
        5
    Sailwww  
    OP
       2022-03-14 18:22:44 +08:00
    @Shazoo
    只有读操作支持,这个当初就是为了我读训练模型时候用的,没有多进程支持速度还是瓶颈...多线程和协程理应也支持?话说这个支持也就是 fork 的时候重建链接就可以了,也不需要别的操作....
    写操作这个是 sqlite 本身的问题,我没遇到使用场景,自己维护锁就没必要了
    bnm965321
        6
    bnm965321  
       2022-03-15 09:59:15 +08:00
    代码写的挺好的,不过我觉得这种场景不如使用 redis/leveldb
    frinstioAKL
        7
    frinstioAKL  
       2022-03-16 11:29:20 +08:00
    有趣, 问下楼主有试过和 lmdb 对比么
    frinstioAKL
        8
    frinstioAKL  
       2022-03-16 11:37:47 +08:00
    最近也考虑同样的场景需求, 正准备自己造轮子结果楼主已经先行一步了.
    除了上面的和 lmdb 对比外, 楼主要不要试试把 pickle 序列化改成用 quickle?( https://github.com/jcrist/quickle) 看 stackoverflow, quickle 易用性和速度似乎是权衡比较好的

    嘿嘿, 等楼主反馈结果(白嫖)
    Sailwww
        9
    Sailwww  
    OP
       2022-03-16 14:34:20 +08:00
    @bnm965321 多谢认可和建议,打算学一下 leveldb 的实现

    @frinstioAKL lmdb 好像不能按 index 索引,是分块的吧?如果是 lmdb 的那种实现,不如尝试和 feather 格式对比(个人理解)

    quickle 试了一下,两个差的不多,quickle 读比 pickle 快 7% ,pickle 写比 quickle 快了 7% (有上下浮动),所以看具体使用场景吧。

    我记得之前有哪个组做强化学习的,为了搞一个分布式系统开源了一个序列化的库好像效率更高,但我一时半会找不到了...
    Sailwww
        10
    Sailwww  
    OP
       2022-03-16 14:37:44 +08:00
    @frinstioAKL 哦抱歉,我记错了,不是分块读取的;我之前用过 lmdb ,不知道是不是之前代码写的烂的缘故,我记得 lmdb 单个文件数据存储,量级越大读起来就越慢...也是因为当初这件事,我后来尝试了 feather 格式,然后出来了这个库...
    frinstioAKL
        11
    frinstioAKL  
       2022-03-16 16:14:49 +08:00
    @Sailwww 谢谢反馈~ quickle 读写快 7% 感觉还是很可观, 写入速度我倒不是很在意. lmdb 量级越大读起来越慢, 请问你这边是遇到了多大的量级呢? 有空我也试试在我的使用场景下对比下, 试试你的库, 再反馈给你
    Sailwww
        12
    Sailwww  
    OP
       2022-03-16 17:52:56 +08:00
    @frinstioAKL 我刚刚路上突然想到一点,我的测试可能有一定错误,因为我存的是数字,可能因为数据太小导致写入速度慢?(这种数据大小导致的某种均匀性我最初还是在 hash 方法里见到的)。我去看了 quickle 提供的 benchimark ,它在 dump 和 load 下好像都是有速度优势的。我看了 @BingoXuan 说的 sqlitedict 的实现,或许可以考虑直接提供一个 backend 参数传入..

    lmdb 当初应该有一两百万了吧,忘了是纯文本场景还是文本图像混合场景了,哦对了 lmdb 里面有个 metadata 空间应该也有上限,当初我好像是用来放 label 的,这个也是弃掉的一个原因。 [随便找了一篇说明文档]( https://mozilla.github.io/firefox-browser-architecture/text/0015-rkv.html#:~:text=LMDB%20by%20default%20has%20a,may%20have%20performance%20impact%20too.)

    > LMDB by default has a maximum key size set as 512 bytes, there is a compile time configuration to change it, though a larger key may have performance impact too
    frinstioAKL
        13
    frinstioAKL  
       2022-03-16 18:21:15 +08:00
    @Sailwww 受教了, lmdb 的 key 居然有大小限制, 这个我还真没超过这个限制过. 我这边存储 metadata 时一般加一个类似于 __labels__, __keys__ 这样的 key, 对应的 value 去存储实际的 label 等信息. 我这边几百万图片超过 500G LMDB 存储, 放 pytorch dataloader 里面暂时没遇到性能瓶颈. 基于 sqlite 的方案我倒是很想试试
    Sailwww
        14
    Sailwww  
    OP
       2022-03-16 18:56:43 +08:00
    @frinstioAKL 似乎因为编解码方式的问题,图片的 sqlite 读取性能好像不是很客观,而且十分占空间,当时踩完坑后采取的是将图片保存成一个 chunk ,然后 sqlite 记录 chunk path 然后读。因为那段时间工期太赶没仔细测试,你可以再试验一下,我也等一波反馈~
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3292 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 11:32 PVG 19:32 LAX 04:32 JFK 07:32
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86