SQLite的LSM键/值引擎的Python绑定
项目描述
lsm
为SQLite的LSM键/值存储提供快速Python绑定。LSM存储引擎最初是作为实验性的SQLite4重写(现在已废弃)的一部分编写的。最近,LSM源代码已移动到SQLite3 源代码树,并经历了一些改进和修复。此项目使用SQLite3源代码树中的LSM代码。
功能
- 嵌入式的零配置数据库。
- 键支持使用游标进行有序遍历。
- 事务性(包括嵌套事务)。
- 基于单写多读MVCC的事务并发模型。
- 磁盘数据库存储在单个文件中。
- 在应用或电源故障的情况下,数据是持久的。
- 线程安全。
- 为读写操作释放GIL(每个连接都有自己的互斥锁)
- 页面压缩(lz4或zstd)
- 零依赖静态库
- Python 3.x。
限制
Python lsm 的源代码托管在 GitHub 上。
如果您在库中遇到任何错误,请 创建一个问题,包括错误描述和相关跟踪信息。
快速入门
以下是一个示例交互式控制台会话,旨在展示 lsm
Python 库的一些基本功能和功能。
首先,实例化一个 LSM
对象,指定数据库文件的路径。
from lsm import LSM
db = LSM('test.ldb')
assert db.open()
更 Pythonic 的变体是使用上下文管理器
from lsm import LSM
with LSM("test.ldb") as db:
assert db.info()
未打开的数据库将引发 RuntimeError
import pytest
from lsm import LSM
db = LSM('test.ldb')
with pytest.raises(RuntimeError):
db.info()
二进制/字符串模式
您应该使用 binary: bool = True
参数选择以何种模式打开数据库。
例如,当您想存储字符串时,只需传递 binary=False
from lsm import LSM
with LSM("test_0.ldb", binary=False) as db:
# must be str for keys and values
db['foo'] = 'bar'
assert db['foo'] == "bar"
否则,您必须将键和值作为 bytes
传递(默认行为)
from lsm import LSM
with LSM("test.ldb") as db:
db[b'foo'] = b'bar'
assert db[b'foo'] == b'bar'
键/值特性
lsm
是一个键/值存储,具有类似字典的 API
from lsm import LSM
with LSM("test.ldb", binary=False) as db:
db['foo'] = 'bar'
assert db['foo'] == 'bar'
数据库尽快应用更改
import pytest
from lsm import LSM
with LSM("test.ldb", binary=False) as db:
for i in range(4):
db[f'k{i}'] = str(i)
assert 'k3' in db
assert 'k4' not in db
del db['k3']
with pytest.raises(KeyError):
print(db['k3'])
默认情况下,当您尝试查找键时,lsm
将搜索精确匹配。如果您要查找的特定键不存在,您也可以搜索最接近的键
import pytest
from lsm import LSM, SEEK_LE, SEEK_GE, SEEK_LEFAST
with LSM("test.ldb", binary=False) as db:
for i in range(4):
db[f'k{i}'] = str(i)
# Here we will match "k1".
assert db['k1xx', SEEK_LE] == '1'
# Here we will match "k1" but do not fetch a value
# In this case the value will always be ``True`` or there will
# be an exception if the key is not found
assert db['k1xx', SEEK_LEFAST] is True
with pytest.raises(KeyError):
print(db['000', SEEK_LEFAST])
# Here we will match "k2".
assert db['k1xx', SEEK_GE] == "2"
LSM
支持其他常见的字典方法,如
keys()
values()
items()
update()
切片和迭代
可以直接迭代数据库,也可以切片。当您正在切片数据库时,起始键和结束键不必存在 - lsm
将找到最接近的键(详细信息请参阅 LSM.fetch_range() 文档)。
from lsm import LSM
with LSM("test_slices.ldb", binary=False) as db:
# clean database
for key in db.keys():
del db[key]
db['foo'] = 'bar'
for i in range(3):
db[f'k{i}'] = str(i)
# Can easily iterate over the database items
assert (
sorted(item for item in db.items()) == [
('foo', 'bar'), ('k0', '0'), ('k1', '1'), ('k2', '2')
]
)
# However, you will not read the entire database into memory, as special
# iterator objects are used.
assert str(db['k0':'k99']).startswith("<lsm_slice object at")
# But you can cast it to the list for example
assert list(db['k0':'k99']) == [('k0', '0'), ('k1', '1'), ('k2', '2')]
您可以使用开放切片。如果下限或上限超出键的范围,则返回空列表。
with LSM("test_slices.ldb", binary=False, readonly=True) as db:
assert list(db['k0':]) == [('k0', '0'), ('k1', '1'), ('k2', '2')]
assert list(db[:'k1']) == [('foo', 'bar'), ('k0', '0'), ('k1', '1')]
assert list(db[:'aaa']) == []
要按逆序检索键或跳过多个项,只需使用第三个切片参数即可。负步值表示逆序,但第一和第二个参数必须是常规顺序。
with LSM("test_slices.ldb", binary=False, readonly=True) as db:
assert list(db['k0':'k99':2]) == [('k0', '0'), ('k2', '2')]
assert list(db['k0'::-1]) == [('k2', '2'), ('k1', '1'), ('k0', '0')]
assert list(db['k0'::-2]) == [('k2', '2'), ('k0', '0')]
assert list(db['k0'::3]) == [('k0', '0')]
您还可以 删除 键的切片,但请注意,删除 不会 包括键本身
with LSM("test_slices.ldb", binary=False) as db:
del db['k0':'k99']
# Note that 'k0' still exists.
assert list(db.items()) == [('foo', 'bar'), ('k0', '0')]
游标
虽然切片可以覆盖大多数用例,但对于更精细的控制,您可以使用游标遍历记录。
from lsm import LSM, SEEK_GE, SEEK_LE
with LSM("test_cursors.ldb", binary=False) as db:
del db["a":"z"]
db["spam"] = "spam"
with db.cursor() as cursor:
cursor.seek('spam')
key, value = cursor.retrieve()
assert key == 'spam'
assert value == 'spam'
游标查找
with LSM("test_cursors.ldb", binary=False) as db:
db.update({'k0': '0', 'k1': '1', 'k2': '2', 'k3': '3', 'foo': 'bar'})
with db.cursor() as cursor:
cursor.first()
key, value = cursor.retrieve()
assert key == "foo"
assert value == "bar"
cursor.last()
key, value = cursor.retrieve()
assert key == "spam"
assert value == "spam"
cursor.previous()
key, value = cursor.retrieve()
assert key == "k3"
assert value == "3"
查找大于或等于 'k0'
的第一个匹配项,然后向前移动直到键小于 'k99'
with LSM("test_cursors.ldb", binary=False) as db:
with db.cursor() as cursor:
cursor.seek("k0", SEEK_GE)
results = []
while cursor.compare("k99") > 0:
key, value = cursor.retrieve()
results.append((key, value))
cursor.next()
assert results == [('k0', '0'), ('k1', '1'), ('k2', '2'), ('k3', '3')]
查找小于或等于 'k99'
的最后一个匹配项,然后向后移动直到键小于 'k0'
with LSM("test_cursors.ldb", binary=False) as db:
with db.cursor() as cursor:
cursor.seek("k99", SEEK_LE)
results = []
while cursor.compare("k0") >= 0:
key, value = cursor.retrieve()
results.append((key, value))
cursor.previous()
assert results == [('k3', '3'), ('k2', '2'), ('k1', '1'), ('k0', '0')]
当您使用完毕时,关闭游标非常重要。因此,建议您使用 LSM.cursor()
上下文管理器,以确保游标正确关闭。
事务
lsm
支持嵌套事务。使用事务的最简单方法是使用 LSM.transaction()
方法,该方法返回一个上下文管理器
from lsm import LSM
with LSM("test_tx.ldb", binary=False) as db:
del db["a":"z"]
for i in range(10):
db[f"k{i}"] = f"{i}"
with LSM("test_tx.ldb", binary=False) as db:
with db.transaction() as tx1:
db['k1'] = '1-mod'
with db.transaction() as tx2:
db['k2'] = '2-mod'
tx2.rollback()
assert db['k1'] == '1-mod'
assert db['k2'] == '2'
您可以在包装块中部分提交或回滚事务
from lsm import LSM
with LSM("test_tx_2.ldb", binary=False) as db:
del db["a":"z"]
for i in range(10):
db[f"k{i}"] = f"{i}"
with LSM("test_tx_2.ldb", binary=False) as db:
with db.transaction() as txn:
db['k1'] = 'outer txn'
# The write operation is preserved.
txn.commit()
db['k1'] = 'outer txn-2'
with db.transaction() as txn2:
# This is committed after the block ends.
db['k1'] = 'inner-txn'
assert db['k1'] == "inner-txn"
# Rolls back both the changes from txn2 and the preceding write.
txn.rollback()
assert db['k1'] == 'outer txn', db['k1']
如果您愿意,也可以显式调用 LSM.begin()
、LSM.commit()
和 LSM.rollback()
。
from lsm import LSM
# fill db
with LSM("test_db_tx.ldb", binary=False) as db:
del db["k":"z"]
for i in range(10):
db[f"k{i}"] = f"{i}"
with LSM("test_db_tx.ldb", binary=False) as db:
# start transaction
db.begin()
db['k1'] = '1-mod'
# nested transaction
db.begin()
db['k2'] = '2-mod'
# rolling back nested transaction
db.rollback()
# comitting top-level transaction
db.commit()
assert db['k1'] == '1-mod'
assert db['k2'] == '2'
感谢
- @coleifer - 此项目受 coleifer/python-lsm-db 的启发。
项目详情
下载文件
下载适合您平台的应用文件。如果您不确定选择哪个,请了解更多关于安装包的信息。
源分布
构建分布
lsm-0.5.4.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 2048586ce2202de895270e557500e86dc2127d44f5943b99091b9deb19380e55 |
|
MD5 | c0255f353109131a4e675c4126c9c3df |
|
BLAKE2b-256 | 066b0ffe3ccab39dc87807aa52ddde66c7947324bbf1827604df571a44c5a64e |
lsm-0.5.4-cp311-cp311-win_amd64.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 812654eeb02b4441445369b8ce2c8fc5a865e1e092e31e80b63f16fd2e3d2b6d |
|
MD5 | 3a3dd66daf539455cc43da69856951b4 |
|
BLAKE2b-256 | 1fb77e63a1f8925aff680b39e4d71a035fc14621d22d6d5db29d8674ab136e39 |
lsm-0.5.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | f20b82b82faf3b88022fcbf2605fd22f21c641a58d849ae870e183cbfc1ffbe2 |
|
MD5 | bf940dd02893cee6578d067e3b2c12de |
|
BLAKE2b-256 | 17e08873804a2e76338ee47a5d99e1f652c294a552d31e0e57c8fc194481e31e |
lsm-0.5.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | e89ec0cee4a86a86373f61bfacdff9c4e8a1527d46e8abbe579766c804af01a9 |
|
MD5 | a0526b9f3b94ea934b6eb6a8c0cf8d10 |
|
BLAKE2b-256 | 1ffe88e2198b84f34b0583354cda3e35965e1b7be181bf6167c230104bbe9ad6 |
lsm-0.5.4-cp311-cp311-macosx_10_9_universal2.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 672b1c37b9c42de0d1090a30b5dc2b0a25b76e6882f4912869be54dda5c8a597 |
|
MD5 | 477eec57e324d14613658a227d8e6636 |
|
BLAKE2b-256 | 8fbbe02a85da9e1da3ad7c150a4e52fb3427110d48daf23ff0d9442d4037b3bc |
lsm-0.5.4-cp310-cp310-win_amd64.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | bb498840c471c36d1a5a798323ab02e8dd0c748d9bfe8388e799e037a5bc46e3 |
|
MD5 | 1e5dca192616d40560dfac103815b0dd |
|
BLAKE2b-256 | ecd424221f9520260b8f812450f1055ad430e00557c1b77d15f623086a99c93a |
lsm-0.5.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 16373c7d6f2d7bcf3cf164d87fa331d33feb561ac2c6a4053d3c2187ae70314a |
|
MD5 | 0b284d101923f9beb70be212acea7ba4 |
|
BLAKE2b-256 | 95296504dc500ba90f279b69052f1a07b1e288eb8627bfe1127b5bbeafb3099d |
哈希值 为 lsm-0.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 9f78ea0ee5324f543c89d28d43abd28e8582450bdc259a85d54b41e6448f66ec |
|
MD5 | 0a169a345662dd55985e2d56381348bc |
|
BLAKE2b-256 | bcc2b5e7cb91dd837cce3a24186343b679aa6cb428b557570b61da8e333f2215 |
哈希值 为 lsm-0.5.4-cp310-cp310-macosx_10_9_universal2.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | acc953e61e75b1efa36d909b604f1237762dedef955b065f77080bb5ccc06b6f |
|
MD5 | 081775682466f06b35c9de985081c110 |
|
BLAKE2b-256 | 2e2c0dc11291fa4abd99e4366e33e9b18116cc93715dcc7406980b69f74fe622 |
哈希值 为 lsm-0.5.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 72e48572e75db24a3ef98aeafcb4e3c8c4b2546025e57bca859aa6e97574dfcd |
|
MD5 | b3df6687e16ac9f52d7ae43bb2766034 |
|
BLAKE2b-256 | 432d0e8548df768694fbe28974d65882ce11cac1c754ba6df08ba5918cf3203d |
哈希值 为 lsm-0.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 9bc285ebd1cc038bdbd15e00abc71a22c15d381a358744bd7816f9fb29955a44 |
|
MD5 | 53142c214b3f658e5473822aac147053 |
|
BLAKE2b-256 | 4c15c342a05fc632eafcc7dacd6f87262257d03def0a48e3226f974326dea52b |
哈希值 为 lsm-0.5.4-cp39-cp39-macosx_10_9_universal2.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 43dd488443eb0347f3ece19f77040888581190bd3f28c76dd217c90674b6f55d |
|
MD5 | bcc8f8a468ed8961da17cdfdce03c720 |
|
BLAKE2b-256 | 02bbddbdd88b68b5379b26c0029d6c4c3dee369f35c5fd8e8e5ae830e20d369d |
哈希值 为 lsm-0.5.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 1f6315cfb014abd49d4570708d97d8894406b3bca8a7b23865935059d156ca08 |
|
MD5 | a52a03262f185b3e60aa25a197b79b29 |
|
BLAKE2b-256 | da740b193cd2cf4aa0b770834cdc75bb487f85dbe62095d1ad60d88d6c3a5e38 |
哈希值 为 lsm-0.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | e8ab1e76acc867b5e72d0974623e3830d25d60e5cf48025b509ee3a0e27b33b8 |
|
MD5 | e69366014a5d578b87ac2fab6ad14e70 |
|
BLAKE2b-256 | 84ce97aa7f86b59d6c276e50340773c35b285ad4215d7fdc8e863bce0946faa6 |
哈希值 为 lsm-0.5.4-cp38-cp38-macosx_11_0_universal2.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 57c4eab9fe6500c8b73333aa5c0fd23b23120ab9bffa512277903238480706ff |
|
MD5 | 70abe5f2ed895fcaa6b68c5cbd165140 |
|
BLAKE2b-256 | f52be7ea2e0b33e2f1dbda75f1e247d0271d0f3c06077dfa113a80e164a17bec |
哈希值 用于 lsm-0.5.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | ebe692d83456fd57bd24c5c057326f15dd517107aee56bdd1a063507234a9ebd |
|
MD5 | 0631b74c515fc5536c7599f11ea6ab66 |
|
BLAKE2b-256 | 2fba150aa501e7ad631738adedaa32350d06523c8d747f7f1c7e769bf7a25ae2 |
哈希值 用于 lsm-0.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 8ccf2ba35e6814868592fa01be379ca2c33b25c558456d6f2b65f3ae6b5cb914 |
|
MD5 | 8e2b39fd81387c708023210f1b750f97 |
|
BLAKE2b-256 | a49dac73c416c539ec7acee73de47a35293cb3eae70815e4b58f3d29ce78da33 |