Skip to main content

Python bindings for SQLite's LSM key/value engine

Project description

lsm

Fast Python bindings for SQLite's LSM key/value store. The LSM storage engine was initially written as part of the experimental SQLite4 rewrite (now abandoned). More recently, the LSM source code was moved into the SQLite3 source tree and has seen some improvements and fixes. This project uses the LSM code from the SQLite3 source tree.

Features:

  • Embedded zero-conf database.
  • Keys support in-order traversal using cursors.
  • Transactional (including nested transactions).
  • Single writer/multiple reader MVCC based transactional concurrency model.
  • On-disk database stored in a single file.
  • Data is durable in the face of application or power failure.
  • Thread-safe.
  • Releases GIL for read and write operations (each connection has own mutex)
  • Page compression (lz4 or zstd)
  • Zero dependency static library
  • Python 3.x.

Limitations:

The source for Python lsm is hosted on GitHub.

If you encounter any bugs in the library, please open an issue, including a description of the bug and any related traceback.

Quick-start

Below is a sample interactive console session designed to show some of the basic features and functionality of the lsm Python library.

To begin, instantiate a LSM object, specifying a path to a database file.

>>> from lsm import LSM
>>> db = LSM('test.ldb')
>>> db.open()
>>> print(db)
<LSM at "/tmp/test.ldb" as 0x10951e450>

More pythonic variant is using context manager:

>>> from lsm import LSM
>>> with LSM("/tmp/test.ldb") as db:
...     print(db)
<LSM at "/tmp/test.ldb" as 0x10951e450>

Binary/string mode

You should select mode for opening the database with binary: bool = True argument.

For example when you want to store strings just pass binary=False:

>>> from lsm import LSM
>>> with LSM("/tmp/test.ldb", binary=False) as db:
...    db['foo'] = 'bar'   # must be str for keys and values
...    print(db['foo'])
bar

Otherwise, you must pass keys and values ad bytes (default behaviour):

>>> from lsm import LSM
>>> with LSM("/tmp/test.ldb") as db:
...    db[b'foo'] = b'bar'   # must be bytes for keys and values
...    print(db[b'foo'])
b'bar'

Key/Value Features

lsm is a key/value store, and has a dictionary-like API:

>>> from lsm import LSM
>>> with LSM("/tmp/test.ldb", binary=False) as db:
...    db['foo'] = 'bar'
...    print(db['foo'])
bar

Database apply changes as soon as possible:

>>> from lsm import LSM
>>> db = LSM("/tmp/test.ldb", binary=False)
>>> db.open()
True
>>> for i in range(4):
...     db[f'k{i}'] = str(i)
...
>>> 'k3' in db
True
>>> 'k4' in db
False
>>> del db['k3']
>>> db['k3']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: "Key 'k3' was not found"

By default when you attempt to look up a key, lsm will search for an exact match. You can also search for the closest key, if the specific key you are searching for does not exist:

>>> from lsm import, LSM, SEEK_LE, SEEK_GE
>>> db = LSM("/tmp/test.ldb", binary=False)
>>> db.open()
True
>>> db['k1xx', SEEK_LE]  # Here we will match "k1".
'1'
>>> db['k1xx', SEEK_GE]  # Here we will match "k2".
'2'

LSM supports other common dictionary methods such as:

  • keys()
  • values()
  • items()
  • update()

Slices and Iteration

The database can be iterated through directly, or sliced. When you are slicing the database the start and end keys need not exist -- lsm will find the closest key (details can be found in the LSM.fetch_range() documentation).

>>> [item for item in db.items()]
[('foo', 'bar'), ('k0', '0'), ('k1', '1'), ('k2', '2')]

>>> db['k0':'k99']
<lsm_slice object at 0x10d4f3500>

>>> list(db['k0':'k99'])
[('k0', '0'), ('k1', '1'), ('k2', '2')]

You can use open-ended slices. If the lower- or upper-bound is outside the range of keys an empty list is returned.

>>> list(db['k0':])
[('k0', '0'), ('k1', '1'), ('k2', '2')]

>>> list(db[:'k1'])
[('foo', 'bar'), ('k0', '0'), ('k1', '1')]

>>> list(db[:'aaa'])
[]

To retrieve keys in reverse order or stepping over more then one item, simply use a third slice argument as usual. Negative step value means reverse order, but first and second arguments must be ordinary ordered.

>>> list(db['k0':'k99':2])
[('k0', '0'), ('k2', '2')]

>>> list(db['k0'::-1])
[('k2', '2'), ('k1', '1'), ('k0', '0')]

>>> list(db['k0'::-2])
[('k2', '2'), ('k0', '0')]


>>> list(db['k0'::3])
[('k0', '0')]

You can also delete slices of keys, but note that the delete will not include the keys themselves:

>>> del db['k0':'k99']

>>> list(db)  # Note that 'k0' still exists.
[('foo', 'bar'), ('k0', '0')]

Cursors

While slicing may cover most use-cases, for finer-grained control you can use cursors for traversing records.

>>> with db.cursor() as cursor:
...     for key, value in cursor:
...         print(key, '=>', value)
...
foo => bar
k0 => 0

>>> db.update({'k1': '1', 'k2': '2', 'k3': '3', 'foo': 'bar'})

>>> with db.cursor() as cursor:
...     cursor.first()
...     print(cursor.key())
...     cursor.last()
...     print(cursor.key())
...     cursor.previous()
...     print(cursor.key())
...
foo
k3
k2

>>> with db.cursor() as cursor:
...     cursor.seek('k0', SEEK_GE)
...     print(list(cursor.fetch_until('k99')))
...
[('k0', '0'), ('k1', '1'), ('k2', '2'), ('k3', '3')]

It is very important to close a cursor when you are through using it. For this reason, it is recommended you use the LSM.cursor() context-manager, which ensures the cursor is closed properly.

Transactions

lsm supports nested transactions. The simplest way to use transactions is with the LSM.transaction() method, which doubles as a context-manager or decorator.

>>> with db.transaction() as txn:
...     db['k1'] = '1-mod'
...     with db.transaction() as txn2:
...         db['k2'] = '2-mod'
...         txn2.rollback()
...
True
>>> print(db['k1'], db['k2'])
1-mod 2

You can commit or roll-back transactions part-way through a wrapped block:

>>> with db.transaction() as txn:
...    db['k1'] = 'outer txn'
...    txn.commit()  # The write is preserved.
...
...    db['k1'] = 'outer txn-2'
...    with db.transaction() as txn2:
...        db['k1'] = 'inner-txn'  # This is commited after the block ends.
...    print(db['k1']  # Prints "inner-txn".)
...    txn.rollback()  # Rolls back both the changes from txn2 and the preceding write.
...    print(db['k1'])
...
1              <- Return value from call to commit().
inner-txn      <- Printed after end of txn2.
True           <- Return value of call to rollback().
outer txn      <- Printed after rollback.

If you like, you can also explicitly call LSM.begin(), LSM.commit(), and LSM.rollback().

>>> db.begin()
>>> db['foo'] = 'baze'
>>> print(db['foo'])
baze
>>> db.rollback()
True
>>> print(db['foo'])
bar

Thanks to @coleifer

This project was inspired by coleifer/python-lsm-db.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lsm-0.2.0.tar.gz (367.9 kB view details)

Uploaded Source

Built Distributions

lsm-0.2.0-cp39-cp39-win_amd64.whl (722.7 kB view details)

Uploaded CPython 3.9 Windows x86-64

lsm-0.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.9 manylinux: glibc 2.5+ x86-64

lsm-0.2.0-cp39-cp39-macosx_10_14_x86_64.whl (968.3 kB view details)

Uploaded CPython 3.9 macOS 10.14+ x86-64

lsm-0.2.0-cp38-cp38-win_amd64.whl (722.9 kB view details)

Uploaded CPython 3.8 Windows x86-64

lsm-0.2.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.8 manylinux: glibc 2.5+ x86-64

lsm-0.2.0-cp38-cp38-macosx_10_14_x86_64.whl (967.7 kB view details)

Uploaded CPython 3.8 macOS 10.14+ x86-64

lsm-0.2.0-cp37-cp37m-win_amd64.whl (718.7 kB view details)

Uploaded CPython 3.7m Windows x86-64

lsm-0.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.7m manylinux: glibc 2.5+ x86-64

lsm-0.2.0-cp37-cp37m-macosx_10_14_x86_64.whl (963.4 kB view details)

Uploaded CPython 3.7m macOS 10.14+ x86-64

lsm-0.2.0-cp36-cp36m-win_amd64.whl (718.7 kB view details)

Uploaded CPython 3.6m Windows x86-64

lsm-0.2.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.6m manylinux: glibc 2.5+ x86-64

lsm-0.2.0-cp36-cp36m-macosx_10_14_x86_64.whl (963.4 kB view details)

Uploaded CPython 3.6m macOS 10.14+ x86-64

File details

Details for the file lsm-0.2.0.tar.gz.

File metadata

  • Download URL: lsm-0.2.0.tar.gz
  • Upload date:
  • Size: 367.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.3.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.0 CPython/3.9.5

File hashes

Hashes for lsm-0.2.0.tar.gz
Algorithm Hash digest
SHA256 cf7ff54f978e4378d112496c7764d90927d7c655b38ae08ebcdbdd7fe1ad45c8
MD5 06e2d81bd99d07dece044e323575aacc
BLAKE2b-256 9a937c6af53b4c8f231cb25551fd69fe28a79c6ba05d9ea0d28c90db1c7e7374

See more details on using hashes here.

File details

Details for the file lsm-0.2.0-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: lsm-0.2.0-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 722.7 kB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.3.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.0 CPython/3.9.5

File hashes

Hashes for lsm-0.2.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 a334e1ac019ec07d849a240e31b19ebeec8ea06478456652ca3ac7985b1a73a4
MD5 68ada18d641ffea29547bf72c14394c9
BLAKE2b-256 96a5c15e3598bb9f65aac5b4ffb4ca6084ae637c7c74cde589ee770816c290a5

See more details on using hashes here.

File details

Details for the file lsm-0.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl.

File metadata

  • Download URL: lsm-0.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl
  • Upload date:
  • Size: 1.3 MB
  • Tags: CPython 3.9, manylinux: glibc 2.5+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.3.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.0 CPython/3.9.5

File hashes

Hashes for lsm-0.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 b4309d50d3d4c37e38d5082604f21087ce70492d79a04863c2d1dfe3fa8cc128
MD5 50cef5965e052c3944a896001acdb455
BLAKE2b-256 ed5c708de8a1b06be7e0a3b0f44d56b2b361d949ea3a9a3bc20e45a81b5abfb3

See more details on using hashes here.

File details

Details for the file lsm-0.2.0-cp39-cp39-macosx_10_14_x86_64.whl.

File metadata

  • Download URL: lsm-0.2.0-cp39-cp39-macosx_10_14_x86_64.whl
  • Upload date:
  • Size: 968.3 kB
  • Tags: CPython 3.9, macOS 10.14+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.3.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.0 CPython/3.9.5

File hashes

Hashes for lsm-0.2.0-cp39-cp39-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 36b98e0d9c64f3dfca374c44d4a4f4ffe831946d4758f09cd7224ef620add27b
MD5 4e0d3642f0491e77cc2ca02e6fe0e831
BLAKE2b-256 a706d3b853a897fc54d480f9d808c6a2746167ccc3971150645147c89ef3dc07

See more details on using hashes here.

File details

Details for the file lsm-0.2.0-cp38-cp38-win_amd64.whl.

File metadata

  • Download URL: lsm-0.2.0-cp38-cp38-win_amd64.whl
  • Upload date:
  • Size: 722.9 kB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.3.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.0 CPython/3.8.10

File hashes

Hashes for lsm-0.2.0-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 671dbd38f3c35d190ae734ee635fa063698081361922d77fe6cce78e6d42269e
MD5 4c491d9e1c9e2ed942c1bbd9f3aa0031
BLAKE2b-256 d9877332834644a949c9213f2ff9077732e367fedba39c4e5d214446c5d9a71f

See more details on using hashes here.

File details

Details for the file lsm-0.2.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl.

File metadata

  • Download URL: lsm-0.2.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl
  • Upload date:
  • Size: 1.3 MB
  • Tags: CPython 3.8, manylinux: glibc 2.5+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.3.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.0 CPython/3.9.5

File hashes

Hashes for lsm-0.2.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 5f1064a7edc7ec3eae71d14858062b95931d23f55649ba481e262a9659f9b1f5
MD5 4736b48cc764f3f17fc5159872653673
BLAKE2b-256 b647babd80d574679f2cfb51dc85b06336c47658a0c18cb3aad923a0192b2921

See more details on using hashes here.

File details

Details for the file lsm-0.2.0-cp38-cp38-macosx_10_14_x86_64.whl.

File metadata

  • Download URL: lsm-0.2.0-cp38-cp38-macosx_10_14_x86_64.whl
  • Upload date:
  • Size: 967.7 kB
  • Tags: CPython 3.8, macOS 10.14+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.3.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.0 CPython/3.8.10

File hashes

Hashes for lsm-0.2.0-cp38-cp38-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 f7a43bb0c73b11ce7e8671086aeaee41c92d34baa9f2ace2c735fae367c57436
MD5 87fc7bfa9c61acd8b7df1845ebc1d0ec
BLAKE2b-256 5cb1c9c0df9a11c0deca3b1cd590a2540397e6286812fd06b2fe10594ebab097

See more details on using hashes here.

File details

Details for the file lsm-0.2.0-cp37-cp37m-win_amd64.whl.

File metadata

  • Download URL: lsm-0.2.0-cp37-cp37m-win_amd64.whl
  • Upload date:
  • Size: 718.7 kB
  • Tags: CPython 3.7m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.0.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.0 CPython/3.7.9

File hashes

Hashes for lsm-0.2.0-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 70bbe3d295a075440f2dab3425f423774d287eccc5d80c121a2eb9e93f1f9378
MD5 3baa7b241de08e60c5d15a8f783dc6a4
BLAKE2b-256 52c65fe5e2f319ec65f006fe1e7221681e3b192a6b4951c29dc6446d3ce7c42b

See more details on using hashes here.

File details

Details for the file lsm-0.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl.

File metadata

  • Download URL: lsm-0.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl
  • Upload date:
  • Size: 1.3 MB
  • Tags: CPython 3.7m, manylinux: glibc 2.5+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.3.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.0 CPython/3.9.5

File hashes

Hashes for lsm-0.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 f6c201f6af8db4bed8e22fe057d0cbc45654f48b0b3c5d7da59c6b5c78abcff9
MD5 cf8318d5f2ec65cc9a0a5f5814f6b9fa
BLAKE2b-256 7320e4748862a16fd95766f4cd621aee8bcdf6620857059ad9234db8e5033e86

See more details on using hashes here.

File details

Details for the file lsm-0.2.0-cp37-cp37m-macosx_10_14_x86_64.whl.

File metadata

  • Download URL: lsm-0.2.0-cp37-cp37m-macosx_10_14_x86_64.whl
  • Upload date:
  • Size: 963.4 kB
  • Tags: CPython 3.7m, macOS 10.14+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.3.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.0 CPython/3.7.10

File hashes

Hashes for lsm-0.2.0-cp37-cp37m-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 632d97ceb23859fef246e9546c6c4d1f66eeb7055e1b1b4382e0f1a8eb13f43a
MD5 77f68e560450c1a966ee1389001ab9b1
BLAKE2b-256 79678f84067102d19b0a0d16318b3e0e67f6bc7fd98fbd6a71b4b3e900ca375b

See more details on using hashes here.

File details

Details for the file lsm-0.2.0-cp36-cp36m-win_amd64.whl.

File metadata

  • Download URL: lsm-0.2.0-cp36-cp36m-win_amd64.whl
  • Upload date:
  • Size: 718.7 kB
  • Tags: CPython 3.6m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.3.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.0 CPython/3.6.8

File hashes

Hashes for lsm-0.2.0-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 b4ebb4b18359d5cc1a0282c641bba179e455bddd224ece12b3aa8b459578b88f
MD5 14e651bea8971897382015b39824af15
BLAKE2b-256 7ef148d92e4c9f17e828300c9f40bfdab9cfeb5d8ee961683dcef26b376db35e

See more details on using hashes here.

File details

Details for the file lsm-0.2.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl.

File metadata

  • Download URL: lsm-0.2.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl
  • Upload date:
  • Size: 1.3 MB
  • Tags: CPython 3.6m, manylinux: glibc 2.5+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.3.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.0 CPython/3.9.5

File hashes

Hashes for lsm-0.2.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 bd8a5628df86fb575520040d06ce926c1a53000f88691a7755231267b2407786
MD5 f70dc26790dc11242ca9808cdfda3a26
BLAKE2b-256 0efa5602b474fc4f6424f90b208a1506c72841ef2d657fa5f72f0ba061fe4985

See more details on using hashes here.

File details

Details for the file lsm-0.2.0-cp36-cp36m-macosx_10_14_x86_64.whl.

File metadata

  • Download URL: lsm-0.2.0-cp36-cp36m-macosx_10_14_x86_64.whl
  • Upload date:
  • Size: 963.4 kB
  • Tags: CPython 3.6m, macOS 10.14+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.3.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.0 CPython/3.6.13

File hashes

Hashes for lsm-0.2.0-cp36-cp36m-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 f8e227583d6699856eefd3d8c19f0fcb197728ea235e634da619c3f6dc5f51a6
MD5 f80732b2e6499ac39878a8e14723828f
BLAKE2b-256 aaec0a8946f118920b0233b9aa7a7ae9d04d96dae8ff26f03cdb38615b5fcbac

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page