All Projects → coleifer → python-lsm-db

coleifer / python-lsm-db

Licence: other
Python bindings for the SQLite4 LSM database.

Programming Languages

c
50402 projects - #5 most used programming language
cython
566 projects
python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to python-lsm-db

sync-client
SyncProxy javascript client with support for all major embedded databases (IndexedDB, SQLite, WebSQL, LokiJS...)
Stars: ✭ 30 (-73.91%)
Mutual labels:  nosql, sqlite, embedded-database
Xodus
Transactional schema-less embedded database used by JetBrains YouTrack and JetBrains Hub.
Stars: ✭ 864 (+651.3%)
Mutual labels:  nosql, embedded-database
Nano Sql
Universal database layer for the client, server & mobile devices. It's like Lego for databases.
Stars: ✭ 717 (+523.48%)
Mutual labels:  nosql, sqlite
Libfpta
Ultra fast, compact, Embedded Database for tabular and semistructured data.
Stars: ✭ 100 (-13.04%)
Mutual labels:  nosql, embedded-database
Inquiry Deprecated
[DEPRECATED]: Prefer Room by Google, or SQLDelight by Square.
Stars: ✭ 264 (+129.57%)
Mutual labels:  nosql, sqlite
Nitrite Java
Java embedded nosql document store
Stars: ✭ 538 (+367.83%)
Mutual labels:  nosql, embedded-database
Cog
A Persistent Embedded Graph Database for Python
Stars: ✭ 90 (-21.74%)
Mutual labels:  nosql, embedded-database
Unqlite Python
Python bindings for the UnQLite embedded NoSQL database
Stars: ✭ 321 (+179.13%)
Mutual labels:  nosql, embedded-database
Litedb.fsharp
Advanced F# Support for LiteDB, an embedded NoSql database for .NET with type-safe query expression through F# quotations
Stars: ✭ 147 (+27.83%)
Mutual labels:  nosql, embedded-database
Db
Data access layer for PostgreSQL, CockroachDB, MySQL, SQLite and MongoDB with ORM-like features.
Stars: ✭ 2,832 (+2362.61%)
Mutual labels:  nosql, sqlite
AloeDB
Light, Embeddable, NoSQL database for Deno 🦕
Stars: ✭ 111 (-3.48%)
Mutual labels:  nosql, embedded-database
Sequelize
An easy-to-use and promise-based multi SQL dialects ORM tool for Node.js
Stars: ✭ 25,422 (+22006.09%)
Mutual labels:  nosql, sqlite
Nodbi
Document DBI connector for R
Stars: ✭ 56 (-51.3%)
Mutual labels:  nosql, sqlite
Vedis Python
Python bindings for the Vedis embedded NoSQL database
Stars: ✭ 106 (-7.83%)
Mutual labels:  nosql, embedded-database
dockage
embedded document/json store
Stars: ✭ 20 (-82.61%)
Mutual labels:  nosql, embedded-database
sophy
Fast Python bindings to Sophia Database
Stars: ✭ 77 (-33.04%)
Mutual labels:  nosql, embedded-database
dbd
dbd is a database prototyping tool that enables data analysts and engineers to quickly load and transform data in SQL databases.
Stars: ✭ 30 (-73.91%)
Mutual labels:  sqlite
pickledb-rs
PickleDB-rs is a lightweight and simple key-value store. It is a Rust version for Python's PickleDB
Stars: ✭ 116 (+0.87%)
Mutual labels:  nosql
sqlite-vtfunc
Implement SQLite table-valued functions with Python
Stars: ✭ 45 (-60.87%)
Mutual labels:  sqlite
pocket-to-sqlite
Create a SQLite database containing data from your Pocket account
Stars: ✭ 56 (-51.3%)
Mutual labels:  sqlite

Python LSM-DB

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.
  • Python 2.x and 3.x.

Limitations:

  • Not tested on Windoze.

The source for Python lsm-db 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-db Python library. Also check out the API documentation.

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

>>> from lsm import LSM
>>> db = LSM('test.ldb')

Key/Value Features

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

>>> db['foo'] = 'bar'
>>> print db['foo']
bar

>>> for i in range(4):
...     db['k%s' % 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>
  File "lsm.pyx", line 973, in lsm.LSM.__getitem__ (lsm.c:7142)
  File "lsm.pyx", line 777, in lsm.LSM.fetch (lsm.c:5756)
  File "lsm.pyx", line 778, in lsm.LSM.fetch (lsm.c:5679)
  File "lsm.pyx", line 1289, in lsm.Cursor.seek (lsm.c:12122)
  File "lsm.pyx", line 1311, in lsm.Cursor.seek (lsm.c:12008)
KeyError: 'k3'

By default when you attempt to look up a key, lsm-db 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 SEEK_LE, SEEK_GE
>>> 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()
  • 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-db will find the closest key (details can be found in the LSM.fetch_range() documentation).

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

>>> db['k0':'k99']
<generator object at 0x7f2ae93072f8>

>>> 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, simply use a higher key as the first parameter of your slice. If you are retrieving an open-ended slice, you can specify True as the step parameter of the slice.

>>> list(db['k1':'aaa'])  # Since 'k1' > 'aaa', keys are retrieved in reverse:
[('k1', '1'), ('k0', '0'), ('foo', 'bar')]

>>> list(db['k1'::True])  # Open-ended slices specify True for step:
[('k1', '1'), ('k0', '0'), ('foo', 'bar')]

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'})

>>> 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-db 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

Reading more

For more information, check out the project's documentation, hosted at readthedocs:

https://lsm-db.readthedocs.io/en/latest/

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].