Package: aiolmdb
aiolmdbAn asyncio wrapper around LMDB.aiolmdb is alpha quality software, expect the API or architecture to change
signifigantly over time.UsageOpening a aiolmdb enviroementimportaiolmdb# Open a aiolmdb enviroment## Takes the same arguments that lmdb.open does.enviroment=aiolmdb.open("/tmp/path/to/enviorment",...)Opening a aiolmdb databaseUnlike pylmdb, aiolmdb does not return a database handle onopen_db, but
rather a full Python object.# Open a databaserecords=enviroment.open_db("records")# Get the default ("" named database) within an enviromentdefault=enviroment.get_default_database()Querying an aiolmdb databaseAll queries against databases return coroutines and are run asynchronously.# Get a value(s) from the databaseresult=awaitdb.get(b'key')# Normal fetch, returned b'value'result=await.db.get(b'key',default=b'')# Defaults to b'' if no key is foundresult=awaitdb.get_multi([b'0',b'1'])# Gets multiple keys at once# Write a value into the databaseawaitdb.put(b'key',b'value')awaitdb.put_multi([(b'k1',b'v1'),(b'k2',b'v2')])# Puts multiple key-valuesatonce,atomically.# Delete a key from the databaseawaitdb.delete(b'key')awaitdb.delete_multi([b'k1',b'k2',b'k3'])# Drop the databaseawaitdb.drop()# Run any arbitrary transactionsdeftransaction_action(txn):returntxn.id()awaitdb.run(transaction_action)Using codersApplications do not operate directly on bytearrays, and require converting
runtime objects to and from serialized bytearrays. To avoid spending additional
time on the main loop running this conversion code, aiolmdb supports adding
database level coders to run this serialization/deserialization logic in the
executor instead of in the main loop. By default, every aiolmdb database uses
theIdentityCoderwhich supports directly writing bytes like objects. Other
coders can be used for both the key and value to change the types of objects
accepted by the API.# Opening a database with specific codersdb=env.open_db("records",key_coder=UInt16Coder(),value_coder=JSONCoder())awaitdb.put(65535,{"key":"value"})# Takes the approriate maching keysawaitdb.get(65535)# Returns {"key": "value"}# Alter the coder for an existing database, useful for altering the enviroment# default database.db.key_coder=StringCoder()db.value_coder=JSONCoder()# Supported CodersIdentityCoder()# Raw bytes coderStringCoder()# String coderUInt16Coder()# 16-bit unsigned integer coderUInt32Coder()# 32-bit unsigned integer coderUInt64Coder()# 64-bit unsigned integer coderJSONCoder()# JSON coder, works with any JSON serializable objectPicleCoder()# Pickle coder, works with any picklable object compression# Create a new JSONCoder, gzipped with compression level 9# Runs the encoded JSON through zlib before writing to database, anddecompresseszlib_json_coder=JSONCoder().compressed(level=9)compressed_db=env.open_db("records",value_coder=zlib_json_coder)# Write your own custom coderfromaiolmdb.codersimportCoderclassCustomCoder(Coder):defserialize(self,obj):# Custom serialization logic## These objects need to have locally immutable state: the objects must not# change how it represents its state for the duration of all concurrent# transactions dealing with the object.## must return a bytes-like objectreturnbufferdefdeserialize(self,buffer):# Custom deserialization logic## aiolmdb uses LMDB transactions with `buffers=True`. this returns a# direct reference to the memory region. This buffer must NOT be modified in# any way. The lifetime of the buffer is also only valid during the scope of# the transaction that fetched it. To use the buffer outside of the context# of the serializer, it must be copied, and references to the buffer must# not be used elsewhere.## Returns the deserialized objectreturndeserialized_objectCaveats and GotchasWrite transactions (put, delete, pop, replace) still block while executed in
the executor. Thus running multiple simultaneous write transactions will
block all other transactions until they complete, one-by-one. Long running
write transactions are strongly discouraged.Due to design limitations, atomic transactions across multiple databases is
currently not easy to do, nor is the code very pythonic.TODOsSupport cursors and range queries