Quick start¶
Connecting to the server¶
Create a connection to the server:
>>> import tarantool
>>> conn = tarantool.Connection('localhost', 3301, user='user', password='pass')
Data manipulation¶
Select¶
select()
a tuple with id 'AAAA'
from
the space demo
using primary index:
>>> resp = conn.select('demo', 'AAAA')
>>> len(resp)
1
>>> resp[0]
['AAAA', 'Alpha']
select()
a tuple with secondary index
key 'Alpha'
from the space demo
with secondary index sec
:
>>> resp = conn.select('demo', 'Alpha', index='sec')
>>> resp
- ['AAAA', 'Alpha']
Insert¶
insert()
the tuple ('BBBB', 'Bravo')
into the space demo
:
>>> conn.insert('demo', ('BBBB', 'Bravo'))
- ['BBBB', 'Bravo']
Throws an error if there is already a tuple with the same primary key.
>>> try:
... conn.insert('demo', ('BBBB', 'Bravo'))
... except Exception as exc:
... print(exc)
...
(3, 'Duplicate key exists in unique index "pk" in space "demo" with old tuple - ["BBBB", "Bravo"] and new tuple - ["BBBB", "Bravo"]')
Replace¶
replace()
inserts the tuple
('CCCC', 'Charlie')
into the space demo
, if there is no tuple
with primary key 'CCCC'
:
>>> conn.replace('demo', ('CCCC', 'Charlie'))
- ['CCCC', 'Charlie']
If there is already a tuple with the same primary key, replaces it:
>>> conn.replace('demo', ('CCCC', 'Charlie-2'))
- ['CCCC', 'Charlie-2']
Update¶
update()
the tuple with id 'BBBB'
placing
the value 'Bravo-2'
into the field 1
:
>>> conn.update('demo', 'BBBB', [('=', 1, 'Bravo-2')])
- ['BBBB', 'Bravo-2']
Field numeration starts from zero, so the field 0
is the first element
in the tuple. Tarantool 2.3.1 and newer supports field name identifiers.
Upsert¶
upsert()
inserts the tuple, if tuple with
id 'DDDD'
not exists. Otherwise, updates tuple fields.
>>> conn.upsert('demo', ('DDDD', 'Delta'), [('=', 1, 'Delta-2')])
>>> conn.select('demo', 'DDDD')
- ['DDDD', 'Delta']
>>> conn.upsert('demo', ('DDDD', 'Delta'), [('=', 1, 'Delta-2')])
>>> conn.select('demo', 'DDDD')
- ['DDDD', 'Delta-2']
Delete¶
delete()
a tuple identified by id 'AAAA'
:
>>> conn.delete('demo', 'AAAA')
- [('AAAA', 'Alpha')]
Creating a space instance¶
An instance of Space
is a named object to access
the key space.
Create a demo
object that will be used to access the space
with id 'demo'
:
>>> demo = conn.space('demo')
You can use the space instance to do data manipulations without specifying space id.
>>> demo.select('AAAA')
- ['AAAA', 'Alpha']
>>> demo.insert(('BBBB', 'Bravo'))
- ['BBBB', 'Bravo']
Call server-side functions¶
call()
a stored Lua procedure:
>>> conn.call("my_add", (1, 2))
- 3
Evaluate Lua code¶
eval()
arbitrary Lua code on a server:
>>> lua_code = r"""
... local a, b = ...
... return a + b
... """
>>> conn.eval(lua_code, (1, 2))
- 3
Execute SQL query¶
execute()
SQL query on a Tarantool server:
>>> conn.execute('insert into "demo" values (:id, :name)', {'id': 'BBBB', 'name': 'Bravo'})
Connecting to a cluster of servers¶
Create a connection to several servers:
>>> import tarantool
>>> conn = tarantool.ConnectionPool(
... [{'host':'localhost', 'port':3301},
... {'host':'localhost', 'port':3302}],
... user='user', password='pass')
ConnectionPool
is best suited to work with
a single replicaset. Its API is the same as a single server
Connection
, but requests support mode
parameter (a tarantool.Mode
value) to choose between
read-write and read-only pool instances:
>>> resp = conn.select('demo', 'AAAA', mode=tarantool.Mode.PREFER_RO)
>>> resp
- ['AAAA', 'Alpha']
Receiving out-of-band messages¶
Receiving out-of-band messages from a server that uses box.session.push
call is supported for methods: call()
,
eval()
, select()
,
insert()
, replace()
,
update()
, upsert()
,
delete()
.
To work with out-of-band messages, 2 optional arguments are used in the methods listed above:
on_push - callback, launched with the received data for each out-of-band message. Two arguments for this callback are expected:
the first is the received from an out-of-band message data.
the second is on_push_ctx, variable for working with callback context (for example, recording the result or pass data to callback).
on_push_ctx - result of the on_push work can be written to this variable, or through this variable you can pass data to on_push callback.
Below is an example of the proposed API with method call()
and insert()
. In the described example, before the end
of the call()
and insert()
,
out-of-band messages are processed via specified callback.
In the example below, two shells are used, in the first we will configure the server:
fiber = require('fiber')
box.cfg({listen = 3301})
box.schema.user.grant(
'guest',
'read,write,execute',
'universe'
)
function server_function()
x = {0,0}
while x[1] < 3 do
x[1] = x[1] + 1
fiber.sleep(1)
box.session.push(x)
end
fiber.sleep(1)
return x
end
In the second shell, we will execute a call()
with receiving out-of-band messages from the server:
import tarantool
def callback(data, on_push_ctx=[]):
print('run callback with data: ', data)
data[0][1] = data[0][1] + 1
on_push_ctx.append(data)
callback_res = []
conn = tarantool.Connection(port=3301)
res = conn.call(
'server_function',
on_push=callback,
on_push_ctx=callback_res
)
# receiving out-of-band messages,
# the conn.call is not finished yet.
>>> run callback with data: [[1, 0]]
>>> run callback with data: [[2, 0]]
>>> run callback with data: [[3, 0]]
# the conn.call is finished now.
print(res)
>>> [3, 0]
print(callback_res)
>>> [[[1, 1]], [[2, 1]], [[3, 1]]]
Let’s go back to the first shell with the server and create a space and a trigger for it:
box.schema.create_space(
'tester', {
format = {
{name = 'id', type = 'unsigned'},
{name = 'name', type = 'string'},
}
})
box.space.tester:create_index(
'primary_index', {
parts = {
{field = 1, type = 'unsigned'},
}
})
function on_replace_callback()
x = {0,0}
while x[1] < 300 do
x[1] = x[1] + 100
box.session.push(x)
end
return x
end
box.space.tester:on_replace(
on_replace_callback
)
Now, in the second shell, we will execute an insert()
with out-of-band message processing:
callback_res = []
conn_pool = tarantool.ConnectionPool(
[{'host':'localhost', 'port':3301}],
user='guest')
res = conn_pool.insert(
'tester',
(1, 'Mike'),
on_push=callback,
on_push_ctx=callback_res,
)
# receiving out-of-band messages,
# the conn_pool.insert is not finished yet.
>>> run callback with data: [[100, 0]]
>>> run callback with data: [[200, 0]]
>>> run callback with data: [[300, 0]]
# the conn_pool.insert is finished now.
print(res)
>>> [1, 'Mike']
print(callback_res)
>>> [[[100, 1]], [[200, 1]], [[300, 1]]]