A fast Tarantool Database connector for Python/asyncio.
asynctnt is a high-performance Tarantool database connector library for Python/asyncio. It was highly inspired by asyncpg module.
asynctnt requires Python 3.7 or later and is supported for Tarantool versions 1.10+.
Use pip to install:
$ pip install asynctnt
Documentation is available here.
insert
, select
, update
, upsert
, call
, eval
, execute
.Decimal
, UUID
and datetime
types natively.tuple
s or by dict
s with
the appropriate API.timeout
value, so if request is
executed for too long, asyncio.TimeoutError is raised.Tarantool config:
box.cfg {
listen = '127.0.0.1:3301'
}
box.once('v1', function()
box.schema.user.grant('guest', 'read,write,execute', 'universe')
local s = box.schema.create_space('tester')
s:create_index('primary')
s:format({
{ name = 'id', type = 'unsigned' },
{ name = 'name', type = 'string' },
{ name = 'uuid', type = 'uuid' },
})
end)
Python code:
import uuid
import asyncio
import asynctnt
async def main():
conn = asynctnt.Connection(host='127.0.0.1', port=3301)
await conn.connect()
for i in range(1, 11):
await conn.insert('tester', [i, 'hello{}'.format(i), uuid.uuid4()])
data = await conn.select('tester', [])
tup = data[0]
print('tuple:', tup)
print(f'{tup[0]=}; {tup["id"]=}')
print(f'{tup[1]=}; {tup["name"]=}')
print(f'{tup[2]=}; {tup["uuid"]=}')
await conn.disconnect()
asyncio.run(main())
Stdout:
(note that you can simultaneously access fields either by indices or by their names)
tuple: <TarantoolTuple id=1 name='hello1' uuid=UUID('ebbad14c-f78c-42e8-bd12-bfcc564443a6')>
tup[0]=1; tup["id"]=1
tup[1]='hello1'; tup["name"]='hello1'
tup[2]=UUID('ebbad14c-f78c-42e8-bd12-bfcc564443a6'); tup["uuid"]=UUID('ebbad14c-f78c-42e8-bd12-bfcc564443a6')
Tarantool 2.x brought out an SQL interface to the database. You can easily use it
in asynctnt
box.cfg {
listen = '127.0.0.1:3301'
}
box.once('v1', function()
box.schema.user.grant('guest', 'read,write,execute', 'universe')
box.execute([[
create table users (
id int primary key,
name text
)
]])
end)
import asyncio
import asynctnt
async def main():
conn = asynctnt.Connection(host='127.0.0.1', port=3301)
await conn.connect()
await conn.execute("insert into users (id, name) values (?, ?)", [1, 'James Bond'])
await conn.execute("insert into users (id, name) values (?, ?)", [2, 'Ethan Hunt'])
data = await conn.execute('select * from users')
for row in data:
print(row)
await conn.disconnect()
asyncio.run(main())
Stdout:
<TarantoolTuple ID=1 NAME='James Bond'>
<TarantoolTuple ID=2 NAME='Ethan Hunt'>
More about SQL features in asynctnt please refer to the documentation
Two performance tests were conducted:
Seq
-- Sequentially calling 40k requests and measuring performanceParallel
-- Sending 200k in 300 parallel coroutinesOn all the benchmarks below wal_mode = none
.
Turning uvloop
on has a massive effect on the performance, so it is recommended to use asynctnt
with it
Benchmark environment
Tarantool:
box.cfg{wal_mode = 'none'}
Seq (uvloop=off) | Seq (uvloop=on) | Parallel (uvloop=off) | Parallel (uvloop=on) | |
---|---|---|---|---|
ping |
12940.93 | 19980.82 | 88341.95 | 215756.24 |
call |
11586.38 | 18783.56 | 74651.40 | 137557.25 |
eval |
10631.19 | 17040.57 | 61077.84 | 121542.42 |
select |
9613.88 | 16718.97 | 61584.07 | 152526.21 |
insert |
10077.10 | 16989.06 | 65594.82 | 135491.25 |
update |
10832.16 | 16562.80 | 63003.31 | 121892.28 |
execute |
10431.75 | 16967.85 | 58377.81 | 96891.61 |
asynctnt is developed and distributed under the Apache 2.0 license.
asynctnt
for tarantool-queue