Skip to content

Commit 269f8b7

Browse files
committed
api: extend connect with fetch_schema param
Added support of the fetch_schema parameter, which allows to ignore schema changes on the server. Closes #219
1 parent 6f0d536 commit 269f8b7

11 files changed

+352
-97
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,5 @@ debian/files
4141
debian/*.substvars
4242

4343
deb_dist
44+
45+
.rocks

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88

99
### Added
1010
- Support custom packer and unpacker factories (#191).
11-
1211
- Support [crud module](https://github.com/tarantool/crud) native API (#205).
12+
- Support of the fetch_schema parameter for connection (#219).
1313

1414
### Changed
1515

docs/source/quick-start.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ Through the :class:`~tarantool.Connection` object, you can access
359359
360360
>>> import tarantool
361361
>>> from tarantool.error import CrudModuleError, CrudModuleManyError, DatabaseError
362-
>>> conn = tarantool.Connection(host='localhost',port=3301)
362+
>>> conn = tarantool.Connection(host='localhost',port=3301,fetch_schema=False)
363363
364364
>>> conn.crud_
365365
conn.crud_count( conn.crud_insert( conn.crud_insert_object_many(

tarantool/connection.py

+58-10
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,8 @@ def __init__(self, host, port,
570570
ssl_ca_file=DEFAULT_SSL_CA_FILE,
571571
ssl_ciphers=DEFAULT_SSL_CIPHERS,
572572
packer_factory=default_packer_factory,
573-
unpacker_factory=default_unpacker_factory):
573+
unpacker_factory=default_unpacker_factory,
574+
fetch_schema=True):
574575
"""
575576
:param host: Server hostname or IP address. Use ``None`` for
576577
Unix sockets.
@@ -710,6 +711,18 @@ def __init__(self, host, port,
710711
callable[[:obj:`~tarantool.Connection`], :obj:`~msgpack.Unpacker`],
711712
optional
712713
714+
:param bool fetch_schema: If ``False``, allows to ignore schema
715+
changes on the server, schema updates are not automatically
716+
loaded. As a result, these methods become unavailable:
717+
:meth:`~tarantool.Connection.replace`,
718+
:meth:`~tarantool.Connection.insert`,
719+
:meth:`~tarantool.Connection.delete`,
720+
:meth:`~tarantool.Connection.upsert`,
721+
:meth:`~tarantool.Connection.update`,
722+
:meth:`~tarantool.Connection.select`,
723+
:meth:`~tarantool.Connection.space`.
724+
:type fetch_schema: :obj:`bool`, optional
725+
713726
:raise: :exc:`~tarantool.error.ConfigurationError`,
714727
:meth:`~tarantool.Connection.connect` exceptions
715728
@@ -740,6 +753,7 @@ def __init__(self, host, port,
740753
self.socket_timeout = socket_timeout
741754
self.reconnect_delay = reconnect_delay
742755
self.reconnect_max_attempts = reconnect_max_attempts
756+
self.fetch_schema = fetch_schema
743757
self.schema = Schema(self)
744758
self.schema_version = 1
745759
self._socket = None
@@ -952,7 +966,8 @@ def connect(self):
952966
if self.transport == SSL_TRANSPORT:
953967
self.wrap_socket_ssl()
954968
self.handshake()
955-
self.load_schema()
969+
if self.fetch_schema:
970+
self.load_schema()
956971
self._check_features()
957972
except SslError as e:
958973
raise e
@@ -1048,7 +1063,8 @@ def _send_request_wo_reconnect(self, request, on_push=None, on_push_ctx=None):
10481063
response = request.response_class(self, self._read_response())
10491064
break
10501065
except SchemaReloadException as e:
1051-
self.update_schema(e.schema_version)
1066+
if self.fetch_schema:
1067+
self.update_schema(e.schema_version)
10521068
continue
10531069

10541070
while response._code == IPROTO_CHUNK:
@@ -1199,6 +1215,18 @@ def flush_schema(self):
11991215
self.schema.flush()
12001216
self.load_schema()
12011217

1218+
def _fetch_schema_support_check(self):
1219+
"""
1220+
Checks the fetch_schema opt of the connection is enabled.
1221+
If the opt is disabled, an exception will be thrown
1222+
about unsupporting the method with fetch_schema=False.
1223+
1224+
:raise: :exc:`~tarantool.error.NotSupportedError`
1225+
"""
1226+
if not self.fetch_schema:
1227+
raise NotSupportedError('This method is not available in ' +
1228+
'connection opened with fetch_schema=False')
1229+
12021230
def call(self, func_name, *args, on_push=None, on_push_ctx=None):
12031231
"""
12041232
Execute a CALL request: call a stored Lua function.
@@ -1296,11 +1324,14 @@ def replace(self, space_name, values, on_push=None, on_push_ctx=None):
12961324
:exc:`~tarantool.error.DatabaseError`,
12971325
:exc:`~tarantool.error.SchemaError`,
12981326
:exc:`~tarantool.error.NetworkError`,
1299-
:exc:`~tarantool.error.SslError`
1327+
:exc:`~tarantool.error.SslError`,
1328+
:exc:`~tarantool.error.NotSupportedError`
13001329
13011330
.. _replace: https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/replace/
13021331
"""
13031332

1333+
self._fetch_schema_support_check()
1334+
13041335
if isinstance(space_name, str):
13051336
space_name = self.schema.get_space(space_name).sid
13061337
if on_push is not None and not callable(on_push):
@@ -1338,7 +1369,7 @@ def authenticate(self, user, password):
13381369
request = RequestAuthenticate(self, self._salt, self.user,
13391370
self.password)
13401371
auth_response = self._send_request_wo_reconnect(request)
1341-
if auth_response.return_code == 0:
1372+
if auth_response.return_code == 0 and self.fetch_schema:
13421373
self.flush_schema()
13431374
return auth_response
13441375

@@ -1483,11 +1514,14 @@ def insert(self, space_name, values, on_push=None, on_push_ctx=None):
14831514
:exc:`~tarantool.error.DatabaseError`,
14841515
:exc:`~tarantool.error.SchemaError`,
14851516
:exc:`~tarantool.error.NetworkError`,
1486-
:exc:`~tarantool.error.SslError`
1517+
:exc:`~tarantool.error.SslError`,
1518+
:exc:`~tarantool.error.NotSupportedError`
14871519
14881520
.. _insert: https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/insert/
14891521
"""
14901522

1523+
self._fetch_schema_support_check()
1524+
14911525
if isinstance(space_name, str):
14921526
space_name = self.schema.get_space(space_name).sid
14931527
if on_push is not None and not callable(on_push):
@@ -1522,11 +1556,14 @@ def delete(self, space_name, key, *, index=0, on_push=None, on_push_ctx=None):
15221556
:exc:`~tarantool.error.DatabaseError`,
15231557
:exc:`~tarantool.error.SchemaError`,
15241558
:exc:`~tarantool.error.NetworkError`,
1525-
:exc:`~tarantool.error.SslError`
1559+
:exc:`~tarantool.error.SslError`,
1560+
:exc:`~tarantool.error.NotSupportedError`
15261561
15271562
.. _delete: https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/delete/
15281563
"""
15291564

1565+
self._fetch_schema_support_check()
1566+
15301567
key = wrap_key(key)
15311568
if isinstance(space_name, str):
15321569
space_name = self.schema.get_space(space_name).sid
@@ -1581,11 +1618,14 @@ def upsert(self, space_name, tuple_value, op_list, *, index=0, on_push=None, on_
15811618
:exc:`~tarantool.error.DatabaseError`,
15821619
:exc:`~tarantool.error.SchemaError`,
15831620
:exc:`~tarantool.error.NetworkError`,
1584-
:exc:`~tarantool.error.SslError`
1621+
:exc:`~tarantool.error.SslError`,
1622+
:exc:`~tarantool.error.NotSupportedError`
15851623
15861624
.. _upsert: https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/upsert/
15871625
"""
15881626

1627+
self._fetch_schema_support_check()
1628+
15891629
if isinstance(space_name, str):
15901630
space_name = self.schema.get_space(space_name).sid
15911631
if isinstance(index, str):
@@ -1669,11 +1709,14 @@ def update(self, space_name, key, op_list, *, index=0, on_push=None, on_push_ctx
16691709
:exc:`~tarantool.error.DatabaseError`,
16701710
:exc:`~tarantool.error.SchemaError`,
16711711
:exc:`~tarantool.error.NetworkError`,
1672-
:exc:`~tarantool.error.SslError`
1712+
:exc:`~tarantool.error.SslError`,
1713+
:exc:`~tarantool.error.NotSupportedError`
16731714
16741715
.. _update: https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/update/
16751716
"""
16761717

1718+
self._fetch_schema_support_check()
1719+
16771720
key = wrap_key(key)
16781721
if isinstance(space_name, str):
16791722
space_name = self.schema.get_space(space_name).sid
@@ -1855,11 +1898,14 @@ def select(self, space_name, key=None, *, offset=0, limit=0xffffffff, index=0, i
18551898
:exc:`~tarantool.error.DatabaseError`,
18561899
:exc:`~tarantool.error.SchemaError`,
18571900
:exc:`~tarantool.error.NetworkError`,
1858-
:exc:`~tarantool.error.SslError`
1901+
:exc:`~tarantool.error.SslError`,
1902+
:exc:`~tarantool.error.NotSupportedError`
18591903
18601904
.. _select: https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/select/
18611905
"""
18621906

1907+
self._fetch_schema_support_check()
1908+
18631909
if iterator is None:
18641910
iterator = ITERATOR_EQ
18651911
if key is None or (isinstance(key, (list, tuple)) and
@@ -1895,6 +1941,8 @@ def space(self, space_name):
18951941
:raise: :exc:`~tarantool.error.SchemaError`
18961942
"""
18971943

1944+
self._fetch_schema_support_check()
1945+
18981946
return Space(self, space_name)
18991947

19001948
def generate_sync(self):

tarantool/connection_pool.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,8 @@ def __init__(self,
376376
call_16=False,
377377
connection_timeout=CONNECTION_TIMEOUT,
378378
strategy_class=RoundRobinStrategy,
379-
refresh_delay=POOL_REFRESH_DELAY):
379+
refresh_delay=POOL_REFRESH_DELAY,
380+
fetch_schema=True):
380381
"""
381382
:param addrs: List of dictionaries describing server addresses:
382383
@@ -447,6 +448,9 @@ def __init__(self,
447448
`box.info.ro`_ status background refreshes, in seconds.
448449
:type connection_timeout: :obj:`float`, optional
449450
451+
:param fetch_schema: Refer to
452+
:paramref:`~tarantool.Connection.params.fetch_schema`.
453+
450454
:raise: :exc:`~tarantool.error.ConfigurationError`,
451455
:class:`~tarantool.Connection` exceptions
452456
@@ -492,7 +496,8 @@ def __init__(self,
492496
ssl_key_file=addr['ssl_key_file'],
493497
ssl_cert_file=addr['ssl_cert_file'],
494498
ssl_ca_file=addr['ssl_ca_file'],
495-
ssl_ciphers=addr['ssl_ciphers'])
499+
ssl_ciphers=addr['ssl_ciphers'],
500+
fetch_schema=fetch_schema)
496501
)
497502

498503
if connect_now:

tarantool/mesh_connection.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,8 @@ def __init__(self, host=None, port=None,
272272
addrs=None,
273273
strategy_class=RoundRobinStrategy,
274274
cluster_discovery_function=None,
275-
cluster_discovery_delay=CLUSTER_DISCOVERY_DELAY):
275+
cluster_discovery_delay=CLUSTER_DISCOVERY_DELAY,
276+
fetch_schema=True):
276277
"""
277278
:param host: Refer to
278279
:paramref:`~tarantool.Connection.params.host`.
@@ -409,6 +410,9 @@ def __init__(self, host=None, port=None,
409410
list refresh.
410411
:type cluster_discovery_delay: :obj:`float`, optional
411412
413+
:param fetch_schema: Refer to
414+
:paramref:`~tarantool.Connection.params.fetch_schema`.
415+
412416
:raises: :exc:`~tarantool.error.ConfigurationError`,
413417
:class:`~tarantool.Connection` exceptions,
414418
:class:`~tarantool.MeshConnection.connect` exceptions
@@ -467,7 +471,8 @@ def __init__(self, host=None, port=None,
467471
ssl_key_file=addr['ssl_key_file'],
468472
ssl_cert_file=addr['ssl_cert_file'],
469473
ssl_ca_file=addr['ssl_ca_file'],
470-
ssl_ciphers=addr['ssl_ciphers'])
474+
ssl_ciphers=addr['ssl_ciphers'],
475+
fetch_schema=fetch_schema)
471476

472477
def connect(self):
473478
"""

tarantool/request.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,13 @@ def header(self, length):
186186
"""
187187

188188
self._sync = self.conn.generate_sync()
189-
header = self._dumps({IPROTO_REQUEST_TYPE: self.request_type,
190-
IPROTO_SYNC: self._sync,
191-
IPROTO_SCHEMA_ID: self.conn.schema_version})
189+
header_fields = {
190+
IPROTO_REQUEST_TYPE: self.request_type,
191+
IPROTO_SYNC: self._sync,
192+
}
193+
if self.conn.fetch_schema:
194+
header_fields[IPROTO_SCHEMA_ID] = self.conn.schema_version
195+
header = self._dumps(header_fields)
192196

193197
return self._dumps(length + len(header)) + header
194198

0 commit comments

Comments
 (0)