You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by is...@apache.org on 2022/05/30 14:47:42 UTC

[ignite-python-thin-client] 01/01: IGNITE-17054: Fix examples and documentation

This is an automated email from the ASF dual-hosted git repository.

isapego pushed a commit to branch ignite-17054
in repository https://gitbox.apache.org/repos/asf/ignite-python-thin-client.git

commit 5b28e6c92afbf8c8aa1cfd6bec4e13779d90b67c
Author: Igor Sapego <is...@apache.org>
AuthorDate: Mon May 30 07:45:08 2022 -0700

    IGNITE-17054: Fix examples and documentation
---
 docs/async_examples.rst         |  48 +++---
 docs/examples.rst               |  90 +++++------
 examples/async_key_value.py     |  19 ++-
 examples/async_sql.py           | 248 ++++-------------------------
 examples/binary_basics.py       |  14 +-
 examples/create_binary.py       |  23 ++-
 examples/expiry_policy.py       |  27 +++-
 examples/get_and_put_complex.py |   8 +-
 examples/helpers/converters.py  |   5 +
 examples/helpers/sql_helper.py  | 193 +++++++++++++++++++++++
 examples/migrate_binary.py      | 103 +++++++------
 examples/read_binary.py         | 334 +++++++++++-----------------------------
 examples/scans.py               |   4 +-
 examples/sql.py                 | 266 +++++---------------------------
 examples/transactions.py        |  11 +-
 examples/type_hints.py          |   3 +-
 16 files changed, 550 insertions(+), 846 deletions(-)

diff --git a/docs/async_examples.rst b/docs/async_examples.rst
index 4ce65ce..644fcfe 100644
--- a/docs/async_examples.rst
+++ b/docs/async_examples.rst
@@ -32,14 +32,14 @@ Firstly, import dependencies.
 
 .. literalinclude:: ../examples/async_key_value.py
   :language: python
-  :lines: 18
+  :lines: 19
 
 Let's connect to cluster and perform key-value queries.
 
 .. literalinclude:: ../examples/async_key_value.py
   :language: python
   :dedent: 4
-  :lines: 23-38
+  :lines: 23-47
 
 Scan
 ====
@@ -49,7 +49,7 @@ that yields the resulting rows.
 .. literalinclude:: ../examples/async_key_value.py
   :language: python
   :dedent: 8
-  :lines: 39-50
+  :lines: 49-60
 
 ExpiryPolicy
 ============
@@ -63,12 +63,12 @@ in cache settings dictionary on creation.
 .. literalinclude:: ../examples/expiry_policy.py
   :language: python
   :dedent: 12
-  :lines: 73-76
+  :lines: 74-77
 
 .. literalinclude:: ../examples/expiry_policy.py
   :language: python
   :dedent: 12
-  :lines: 82-90
+  :lines: 83-91
 
 Secondly, expiry policy can be set for all cache operations, which are done under decorator. To create it use
 :py:meth:`~pyignite.cache.BaseCache.with_expire_policy`
@@ -76,7 +76,7 @@ Secondly, expiry policy can be set for all cache operations, which are done unde
 .. literalinclude:: ../examples/expiry_policy.py
   :language: python
   :dedent: 12
-  :lines: 97-106
+  :lines: 98-107
 
 Transactions
 ------------
@@ -132,41 +132,44 @@ First let us establish a connection.
 .. literalinclude:: ../examples/async_sql.py
   :language: python
   :dedent: 4
-  :lines: 197-198
+  :lines: 24-25
 
 Then create tables. Begin with `Country` table, than proceed with related
 tables `City` and `CountryLanguage`.
 
-.. literalinclude:: ../examples/async_sql.py
+.. literalinclude:: ../examples/helpers/sql_helper.py
   :language: python
-  :lines: 25-42, 51-59, 67-74
+  :dedent: 4
+  :lines: 27-43, 53-60, 68-74
 
 .. literalinclude:: ../examples/async_sql.py
   :language: python
   :dedent: 4
-  :lines: 199-205
+  :lines: 27-32
 
 Create indexes.
 
-.. literalinclude:: ../examples/async_sql.py
+.. literalinclude:: ../examples/helpers/sql_helper.py
   :language: python
-  :lines: 60-62, 75-77
+  :dedent: 4
+  :lines: 62, 76
 
 .. literalinclude:: ../examples/async_sql.py
   :language: python
   :dedent: 8
-  :lines: 207-209
+  :lines: 35-36
 
 Fill tables with data.
 
-.. literalinclude:: ../examples/async_sql.py
+.. literalinclude:: ../examples/helpers/sql_helper.py
   :language: python
-  :lines: 43-50, 63-66, 78-81
+  :dedent: 4
+  :lines: 45-51, 64-66, 78-80
 
 .. literalinclude:: ../examples/async_sql.py
   :language: python
   :dedent: 8
-  :lines: 212-223
+  :lines: 39-49
 
 Now let us answer some questions.
 
@@ -176,7 +179,7 @@ What are the 10 largest cities in our data sample (population-wise)?
 .. literalinclude:: ../examples/async_sql.py
   :language: python
   :dedent: 8
-  :lines: 225-243
+  :lines: 52-66
 
 The :py:meth:`~pyignite.aio_client.AioClient.sql` method returns :py:class:`~pyignite.cursors.AioSqlFieldsCursor`,
 that yields the resulting rows.
@@ -193,7 +196,7 @@ of :py:class:`~pyignite.cursors.AioSqlFieldsCursor`
 .. literalinclude:: ../examples/async_sql.py
   :language: python
   :dedent: 8
-  :lines: 246-271
+  :lines: 69-95
 
 Display all the information about a given city
 ==============================================
@@ -201,18 +204,19 @@ Display all the information about a given city
 .. literalinclude:: ../examples/async_sql.py
   :language: python
   :dedent: 8
-  :lines: 273-288
+  :lines: 98-110
 
 Finally, delete the tables used in this example with the following queries:
 
-.. literalinclude:: ../examples/async_sql.py
+.. literalinclude:: ../examples/helpers/sql_helper.py
   :language: python
-  :lines: 83
+  :dedent: 4
+  :lines: 82
 
 .. literalinclude:: ../examples/async_sql.py
   :language: python
   :dedent: 8
-  :lines: 290-297
+  :lines: 113-115
 
 
 
diff --git a/docs/examples.rst b/docs/examples.rst
index 4ca0910..8f40b91 100644
--- a/docs/examples.rst
+++ b/docs/examples.rst
@@ -71,7 +71,7 @@ File: `type_hints.py`_
 .. literalinclude:: ../examples/type_hints.py
   :language: python
   :dedent: 4
-  :lines: 24-48
+  :lines: 23-47
 
 As a rule of thumb:
 
@@ -97,12 +97,12 @@ in cache settings dictionary on creation.
 .. literalinclude:: ../examples/expiry_policy.py
   :language: python
   :dedent: 12
-  :lines: 32-35
+  :lines: 33-36
 
 .. literalinclude:: ../examples/expiry_policy.py
   :language: python
   :dedent: 12
-  :lines: 41-47
+  :lines: 42-48
 
 Secondly, expiry policy can be set for all cache operations, which are done under decorator. To create it use
 :py:meth:`~pyignite.cache.BaseCache.with_expire_policy`
@@ -110,7 +110,7 @@ Secondly, expiry policy can be set for all cache operations, which are done unde
 .. literalinclude:: ../examples/expiry_policy.py
   :language: python
   :dedent: 12
-  :lines: 54-61
+  :lines: 55-62
 
 Scan
 ====
@@ -124,7 +124,7 @@ Let us put some data in cache.
 .. literalinclude:: ../examples/scans.py
   :language: python
   :dedent: 4
-  :lines: 20-29
+  :lines: 22-31
 
 :py:meth:`~pyignite.cache.Cache.scan` returns a cursor, that yields
 two-tuples of key and value. You can iterate through the generated pairs
@@ -133,14 +133,14 @@ in a safe manner:
 .. literalinclude:: ../examples/scans.py
   :language: python
   :dedent: 4
-  :lines: 31-39
+  :lines: 33-41
 
 Or, alternatively, you can convert the cursor to dictionary in one go:
 
 .. literalinclude:: ../examples/scans.py
   :language: python
   :dedent: 4
-  :lines: 41-50
+  :lines: 43-52
 
 But be cautious: if the cache contains a large set of data, the dictionary
 may consume too much memory!
@@ -158,7 +158,7 @@ each of the collection type. Second comes the data value.
 
 .. literalinclude:: ../examples/get_and_put_complex.py
   :language: python
-  :lines: 19
+  :lines: 17
 
 Map
 ===
@@ -175,7 +175,7 @@ Since CPython 3.6 all dictionaries became de facto ordered. You can always use
 .. literalinclude:: ../examples/get_and_put_complex.py
   :language: python
   :dedent: 4
-  :lines: 26-38
+  :lines: 22-36
 
 Collection
 ==========
@@ -192,7 +192,7 @@ and you always get `list` back.
 .. literalinclude:: ../examples/get_and_put_complex.py
   :language: python
   :dedent: 4
-  :lines: 40-54
+  :lines: 38-52
 
 Object array
 ============
@@ -204,7 +204,7 @@ contents. But it still can be used for interoperability with Java.
 .. literalinclude:: ../examples/get_and_put_complex.py
   :language: python
   :dedent: 4
-  :lines: 56-65
+  :lines: 54-63
 
 
 Transactions
@@ -265,41 +265,44 @@ First let us establish a connection.
 
 .. literalinclude:: ../examples/sql.py
   :language: python
-  :lines: 195-196
+  :lines: 20-21
 
 Then create tables. Begin with `Country` table, than proceed with related
 tables `City` and `CountryLanguage`.
 
-.. literalinclude:: ../examples/sql.py
+.. literalinclude:: ../examples/helpers/sql_helper.py
   :language: python
-  :lines: 25-42, 51-59, 67-74
+  :dedent: 4
+  :lines: 27-43, 53-60, 68-74
 
 .. literalinclude:: ../examples/sql.py
   :language: python
   :dedent: 4
-  :lines: 199-204
+  :lines: 23-28
 
 Create indexes.
 
-.. literalinclude:: ../examples/sql.py
+.. literalinclude:: ../examples/helpers/sql_helper.py
   :language: python
-  :lines: 60-62, 75-77
+  :dedent: 4
+  :lines: 62, 76
 
 .. literalinclude:: ../examples/sql.py
   :language: python
   :dedent: 4
-  :lines: 207-208
+  :lines: 31-32
 
 Fill tables with data.
 
-.. literalinclude:: ../examples/sql.py
+.. literalinclude:: ../examples/helpers/sql_helper.py
   :language: python
-  :lines: 43-50, 63-66, 78-81
+  :dedent: 4
+  :lines: 45-51, 64-66, 78-80
 
 .. literalinclude:: ../examples/sql.py
   :language: python
   :dedent: 4
-  :lines: 211-218
+  :lines: 35-42
 
 Data samples are taken from `PyIgnite GitHub repository`_.
 
@@ -311,7 +314,7 @@ What are the 10 largest cities in our data sample (population-wise)?
 .. literalinclude:: ../examples/sql.py
   :language: python
   :dedent: 4
-  :lines: 24, 221-238
+  :lines: 45-59
 
 The :py:meth:`~pyignite.client.Client.sql` method returns a generator,
 that yields the resulting rows.
@@ -327,7 +330,7 @@ column names as a first yield. You can access field names with Python built-in
 .. literalinclude:: ../examples/sql.py
   :language: python
   :dedent: 4
-  :lines: 241-266
+  :lines: 62-88
 
 Display all the information about a given city
 ==============================================
@@ -335,18 +338,18 @@ Display all the information about a given city
 .. literalinclude:: ../examples/sql.py
   :language: python
   :dedent: 4
-  :lines: 268-283
+  :lines: 92-103
 
 Finally, delete the tables used in this example with the following queries:
 
-.. literalinclude:: ../examples/sql.py
+.. literalinclude:: ../examples/helpers/sql_helper.py
   :language: python
-  :lines: 82-83
+  :lines: 82
 
 .. literalinclude:: ../examples/sql.py
   :language: python
   :dedent: 4
-  :lines: 285-291
+  :lines: 106-107
 
 .. _complex_object_usage:
 
@@ -389,7 +392,7 @@ automatically when reading Complex objects.
 .. literalinclude:: ../examples/binary_basics.py
   :language: python
   :dedent: 4
-  :lines: 32-34, 39-42, 48-49
+  :lines: 36-38, 40-43, 45-46
 
 Here you can see how :class:`~pyignite.binary.GenericObjectMeta` uses
 `attrs`_ package internally for creating nice `__init__()` and `__repr__()`
@@ -416,14 +419,14 @@ Anyway, you can reuse the autogenerated dataclass for subsequent writes:
 .. literalinclude:: ../examples/binary_basics.py
   :language: python
   :dedent: 4
-  :lines: 52, 33-37
+  :lines: 50, 32-34
 
 :class:`~pyignite.binary.GenericObjectMeta` can also be used directly
 for creating custom classes:
 
 .. literalinclude:: ../examples/binary_basics.py
   :language: python
-  :lines: 18-27
+  :lines: 20-25
 
 Note how the `Person` class is defined. `schema` is a
 :class:`~pyignite.binary.GenericObjectMeta` metaclass parameter.
@@ -443,7 +446,7 @@ register said class explicitly with your client:
 .. literalinclude:: ../examples/binary_basics.py
   :language: python
   :dedent: 4
-  :lines: 50
+  :lines: 48
 
 Now, when we dealt with the basics of `pyignite` implementation of Complex
 Objects, let us move on to more elaborate examples.
@@ -465,7 +468,7 @@ Let us do it again and examine the Ignite storage afterwards.
 .. literalinclude:: ../examples/read_binary.py
   :language: python
   :dedent: 4
-  :lines: 222-229
+  :lines: 49-51
 
 We can see that Ignite created a cache for each of our tables. The caches are
 conveniently named using ‘`SQL_<schema name>_<table name>`’ pattern.
@@ -476,7 +479,7 @@ using a :py:attr:`~pyignite.cache.Cache.settings` property.
 .. literalinclude:: ../examples/read_binary.py
   :language: python
   :dedent: 4
-  :lines: 231-251
+  :lines: 53-103
 
 The values of `value_type_name` and `key_type_name` are names of the binary
 types. The `City` table's key fields are stored using `key_type_name` type,
@@ -489,7 +492,7 @@ functions and verify the correctness of the result.
 .. literalinclude:: ../examples/read_binary.py
   :language: python
   :dedent: 4
-  :lines: 253-267
+  :lines: 106-115
 
 What we see is a tuple of key and value, extracted from the cache. Both key
 and value are represent Complex objects. The dataclass names are the same
@@ -525,28 +528,27 @@ These are the necessary steps to perform the task.
 .. literalinclude:: ../examples/create_binary.py
   :language: python
   :dedent: 4
-  :lines: 24-63
+  :lines: 31-69
 
 2. Define Complex object data class.
 
 .. literalinclude:: ../examples/create_binary.py
   :language: python
-  :dedent: 4
-  :lines: 64-75
+  :lines: 21-26
 
 3. Insert row.
 
 .. literalinclude:: ../examples/create_binary.py
   :language: python
   :dedent: 4
-  :lines: 76-80
+  :lines: 71-75
 
 Now let us make sure that our cache really can be used with SQL functions.
 
 .. literalinclude:: ../examples/create_binary.py
   :language: python
   :dedent: 4
-  :lines: 82-87
+  :lines: 77-82
 
 Note, however, that the cache we create can not be dropped with DDL command.
 It should be deleted as any other key-value cache.
@@ -554,7 +556,7 @@ It should be deleted as any other key-value cache.
 .. literalinclude:: ../examples/create_binary.py
   :language: python
   :dedent: 4
-  :lines: 89-96
+  :lines: 84-91
 
 Migrate
 =======
@@ -574,7 +576,7 @@ First get the vouchers' cache.
 .. literalinclude:: ../examples/migrate_binary.py
   :language: python
   :dedent: 4
-  :lines: 111
+  :lines: 109
 
 If you do not store the schema of the Complex object in code, you can obtain
 it as a dataclass property with
@@ -583,20 +585,20 @@ it as a dataclass property with
 .. literalinclude:: ../examples/migrate_binary.py
   :language: python
   :dedent: 4
-  :lines: 116-120
+  :lines: 115-119
 
 Let us modify the schema and create a new Complex object class with an updated
 schema.
 
 .. literalinclude:: ../examples/migrate_binary.py
   :language: python
-  :lines: 122-138
+  :lines: 121-137
 
 Now migrate the data from the old schema to the new one.
 
 .. literalinclude:: ../examples/migrate_binary.py
   :language: python
-  :lines: 141-190
+  :lines: 140-190
 
 At this moment all the fields, defined in both of our schemas, can be
 available in the resulting binary object, depending on which schema was used
diff --git a/examples/async_key_value.py b/examples/async_key_value.py
index 76dac34..7379874 100644
--- a/examples/async_key_value.py
+++ b/examples/async_key_value.py
@@ -14,6 +14,7 @@
 # limitations under the License.
 
 import asyncio
+from pprint import pprint
 
 from pyignite import AioClient
 
@@ -32,9 +33,18 @@ async def main():
 
         # Key-value queries.
         print(await cache.get('key_10'))
-        print(await cache.get_all([f'key_{i}' for i in range(0, 10)]))
         # value_10
-        # {'key_3': 'value_3', 'key_2': 'value_2', 'key_1': 'value_1','....}
+        pprint(await cache.get_all([f'key_{i}' for i in range(0, 10)]))
+        # {'key_0': 'value_0',
+        #  'key_1': 'value_1',
+        #  'key_2': 'value_2',
+        #  'key_3': 'value_3',
+        #  'key_4': 'value_4',
+        #  'key_5': 'value_5',
+        #  'key_6': 'value_6',
+        #  'key_7': 'value_7',
+        #  'key_8': 'value_8',
+        #  'key_9': 'value_9'}
 
         # Scan query.
         async with cache.scan() as cursor:
@@ -52,5 +62,6 @@ async def main():
         # Clean up.
         await cache.destroy()
 
-loop = asyncio.get_event_loop()
-loop.run_until_complete(main())
+
+if __name__ == '__main__':
+    asyncio.run(main())
diff --git a/examples/async_sql.py b/examples/async_sql.py
index ffd2939..d8de9f6 100644
--- a/examples/async_sql.py
+++ b/examples/async_sql.py
@@ -14,220 +14,43 @@
 # limitations under the License.
 
 import asyncio
-from decimal import Decimal
 
+from helpers.sql_helper import TableNames, Query, TestData
 from pyignite import AioClient
 
 
-COUNTRY_TABLE_NAME = 'Country'
-CITY_TABLE_NAME = 'City'
-LANGUAGE_TABLE_NAME = 'CountryLanguage'
-
-COUNTRY_CREATE_TABLE_QUERY = '''CREATE TABLE Country (
-    Code CHAR(3) PRIMARY KEY,
-    Name CHAR(52),
-    Continent CHAR(50),
-    Region CHAR(26),
-    SurfaceArea DECIMAL(10,2),
-    IndepYear SMALLINT(6),
-    Population INT(11),
-    LifeExpectancy DECIMAL(3,1),
-    GNP DECIMAL(10,2),
-    GNPOld DECIMAL(10,2),
-    LocalName CHAR(45),
-    GovernmentForm CHAR(45),
-    HeadOfState CHAR(60),
-    Capital INT(11),
-    Code2 CHAR(2)
-)'''
-
-COUNTRY_INSERT_QUERY = '''INSERT INTO Country(
-    Code, Name, Continent, Region,
-    SurfaceArea, IndepYear, Population,
-    LifeExpectancy, GNP, GNPOld,
-    LocalName, GovernmentForm, HeadOfState,
-    Capital, Code2
-) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'''
-
-CITY_CREATE_TABLE_QUERY = '''CREATE TABLE City (
-    ID INT(11),
-    Name CHAR(35),
-    CountryCode CHAR(3),
-    District CHAR(20),
-    Population INT(11),
-    PRIMARY KEY (ID, CountryCode)
-) WITH "affinityKey=CountryCode"'''
-
-CITY_CREATE_INDEX = '''
-CREATE INDEX idx_country_code ON city (CountryCode)'''
-
-CITY_INSERT_QUERY = '''INSERT INTO City(
-    ID, Name, CountryCode, District, Population
-) VALUES (?, ?, ?, ?, ?)'''
-
-LANGUAGE_CREATE_TABLE_QUERY = '''CREATE TABLE CountryLanguage (
-    CountryCode CHAR(3),
-    Language CHAR(30),
-    IsOfficial BOOLEAN,
-    Percentage DECIMAL(4,1),
-    PRIMARY KEY (CountryCode, Language)
-) WITH "affinityKey=CountryCode"'''
-
-LANGUAGE_CREATE_INDEX = '''
-CREATE INDEX idx_lang_country_code ON CountryLanguage (CountryCode)'''
-
-LANGUAGE_INSERT_QUERY = '''INSERT INTO CountryLanguage(
-    CountryCode, Language, IsOfficial, Percentage
-) VALUES (?, ?, ?, ?)'''
-
-DROP_TABLE_QUERY = '''DROP TABLE {} IF EXISTS'''
-
-COUNTRY_DATA = [
-    [
-        'USA', 'United States', 'North America', 'North America',
-        Decimal('9363520.00'), 1776, 278357000,
-        Decimal('77.1'), Decimal('8510700.00'), Decimal('8110900.00'),
-        'United States', 'Federal Republic', 'George W. Bush',
-        3813, 'US',
-    ],
-    [
-        'IND', 'India', 'Asia', 'Southern and Central Asia',
-        Decimal('3287263.00'), 1947, 1013662000,
-        Decimal('62.5'), Decimal('447114.00'), Decimal('430572.00'),
-        'Bharat/India', 'Federal Republic', 'Kocheril Raman Narayanan',
-        1109, 'IN',
-    ],
-    [
-        'CHN', 'China', 'Asia', 'Eastern Asia',
-        Decimal('9572900.00'), -1523, 1277558000,
-        Decimal('71.4'), Decimal('982268.00'), Decimal('917719.00'),
-        'Zhongquo', 'PeoplesRepublic', 'Jiang Zemin',
-        1891, 'CN',
-    ],
-]
-
-CITY_DATA = [
-    [3793, 'New York', 'USA', 'New York', 8008278],
-    [3794, 'Los Angeles', 'USA', 'California', 3694820],
-    [3795, 'Chicago', 'USA', 'Illinois', 2896016],
-    [3796, 'Houston', 'USA', 'Texas', 1953631],
-    [3797, 'Philadelphia', 'USA', 'Pennsylvania', 1517550],
-    [3798, 'Phoenix', 'USA', 'Arizona', 1321045],
-    [3799, 'San Diego', 'USA', 'California', 1223400],
-    [3800, 'Dallas', 'USA', 'Texas', 1188580],
-    [3801, 'San Antonio', 'USA', 'Texas', 1144646],
-    [3802, 'Detroit', 'USA', 'Michigan', 951270],
-    [3803, 'San Jose', 'USA', 'California', 894943],
-    [3804, 'Indianapolis', 'USA', 'Indiana', 791926],
-    [3805, 'San Francisco', 'USA', 'California', 776733],
-    [1024, 'Mumbai (Bombay)', 'IND', 'Maharashtra', 10500000],
-    [1025, 'Delhi', 'IND', 'Delhi', 7206704],
-    [1026, 'Calcutta [Kolkata]', 'IND', 'West Bengali', 4399819],
-    [1027, 'Chennai (Madras)', 'IND', 'Tamil Nadu', 3841396],
-    [1028, 'Hyderabad', 'IND', 'Andhra Pradesh', 2964638],
-    [1029, 'Ahmedabad', 'IND', 'Gujarat', 2876710],
-    [1030, 'Bangalore', 'IND', 'Karnataka', 2660088],
-    [1031, 'Kanpur', 'IND', 'Uttar Pradesh', 1874409],
-    [1032, 'Nagpur', 'IND', 'Maharashtra', 1624752],
-    [1033, 'Lucknow', 'IND', 'Uttar Pradesh', 1619115],
-    [1034, 'Pune', 'IND', 'Maharashtra', 1566651],
-    [1035, 'Surat', 'IND', 'Gujarat', 1498817],
-    [1036, 'Jaipur', 'IND', 'Rajasthan', 1458483],
-    [1890, 'Shanghai', 'CHN', 'Shanghai', 9696300],
-    [1891, 'Peking', 'CHN', 'Peking', 7472000],
-    [1892, 'Chongqing', 'CHN', 'Chongqing', 6351600],
-    [1893, 'Tianjin', 'CHN', 'Tianjin', 5286800],
-    [1894, 'Wuhan', 'CHN', 'Hubei', 4344600],
-    [1895, 'Harbin', 'CHN', 'Heilongjiang', 4289800],
-    [1896, 'Shenyang', 'CHN', 'Liaoning', 4265200],
-    [1897, 'Kanton [Guangzhou]', 'CHN', 'Guangdong', 4256300],
-    [1898, 'Chengdu', 'CHN', 'Sichuan', 3361500],
-    [1899, 'Nanking [Nanjing]', 'CHN', 'Jiangsu', 2870300],
-    [1900, 'Changchun', 'CHN', 'Jilin', 2812000],
-    [1901, 'Xi´an', 'CHN', 'Shaanxi', 2761400],
-    [1902, 'Dalian', 'CHN', 'Liaoning', 2697000],
-    [1903, 'Qingdao', 'CHN', 'Shandong', 2596000],
-    [1904, 'Jinan', 'CHN', 'Shandong', 2278100],
-    [1905, 'Hangzhou', 'CHN', 'Zhejiang', 2190500],
-    [1906, 'Zhengzhou', 'CHN', 'Henan', 2107200],
-]
-
-LANGUAGE_DATA = [
-    ['USA', 'Chinese', False, Decimal('0.6')],
-    ['USA', 'English', True, Decimal('86.2')],
-    ['USA', 'French', False, Decimal('0.7')],
-    ['USA', 'German', False, Decimal('0.7')],
-    ['USA', 'Italian', False, Decimal('0.6')],
-    ['USA', 'Japanese', False, Decimal('0.2')],
-    ['USA', 'Korean', False, Decimal('0.3')],
-    ['USA', 'Polish', False, Decimal('0.3')],
-    ['USA', 'Portuguese', False, Decimal('0.2')],
-    ['USA', 'Spanish', False, Decimal('7.5')],
-    ['USA', 'Tagalog', False, Decimal('0.4')],
-    ['USA', 'Vietnamese', False, Decimal('0.2')],
-    ['IND', 'Asami', False, Decimal('1.5')],
-    ['IND', 'Bengali', False, Decimal('8.2')],
-    ['IND', 'Gujarati', False, Decimal('4.8')],
-    ['IND', 'Hindi', True, Decimal('39.9')],
-    ['IND', 'Kannada', False, Decimal('3.9')],
-    ['IND', 'Malajalam', False, Decimal('3.6')],
-    ['IND', 'Marathi', False, Decimal('7.4')],
-    ['IND', 'Orija', False, Decimal('3.3')],
-    ['IND', 'Punjabi', False, Decimal('2.8')],
-    ['IND', 'Tamil', False, Decimal('6.3')],
-    ['IND', 'Telugu', False, Decimal('7.8')],
-    ['IND', 'Urdu', False, Decimal('5.1')],
-    ['CHN', 'Chinese', True, Decimal('92.0')],
-    ['CHN', 'Dong', False, Decimal('0.2')],
-    ['CHN', 'Hui', False, Decimal('0.8')],
-    ['CHN', 'Mantšu', False, Decimal('0.9')],
-    ['CHN', 'Miao', False, Decimal('0.7')],
-    ['CHN', 'Mongolian', False, Decimal('0.4')],
-    ['CHN', 'Puyi', False, Decimal('0.2')],
-    ['CHN', 'Tibetan', False, Decimal('0.4')],
-    ['CHN', 'Tujia', False, Decimal('0.5')],
-    ['CHN', 'Uighur', False, Decimal('0.6')],
-    ['CHN', 'Yi', False, Decimal('0.6')],
-    ['CHN', 'Zhuang', False, Decimal('1.4')],
-]
-
-
 async def main():
     # establish connection
     client = AioClient()
     async with client.connect('127.0.0.1', 10800):
         # create tables
         for query in [
-            COUNTRY_CREATE_TABLE_QUERY,
-            CITY_CREATE_TABLE_QUERY,
-            LANGUAGE_CREATE_TABLE_QUERY,
+            Query.COUNTRY_CREATE_TABLE,
+            Query.CITY_CREATE_TABLE,
+            Query.LANGUAGE_CREATE_TABLE,
         ]:
             await client.sql(query)
 
         # create indices
-        for query in [CITY_CREATE_INDEX, LANGUAGE_CREATE_INDEX]:
+        for query in [Query.CITY_CREATE_INDEX, Query.LANGUAGE_CREATE_INDEX]:
             await client.sql(query)
 
         # load data concurrently.
         await asyncio.gather(*[
-            client.sql(COUNTRY_INSERT_QUERY, query_args=row) for row in COUNTRY_DATA
+            client.sql(Query.COUNTRY_INSERT, query_args=row) for row in TestData.COUNTRY
         ])
 
         await asyncio.gather(*[
-            client.sql(CITY_INSERT_QUERY, query_args=row) for row in CITY_DATA
+            client.sql(Query.CITY_INSERT, query_args=row) for row in TestData.CITY
         ])
 
         await asyncio.gather(*[
-            client.sql(LANGUAGE_INSERT_QUERY, query_args=row) for row in LANGUAGE_DATA
+            client.sql(Query.LANGUAGE_INSERT, query_args=row) for row in TestData.LANGUAGE
         ])
 
         # 10 most populated cities (with pagination)
-        MOST_POPULATED_QUERY = '''
-        SELECT name, population FROM City ORDER BY population DESC LIMIT 10'''
-
-        async with client.sql(MOST_POPULATED_QUERY) as cursor:
+        async with client.sql('SELECT name, population FROM City ORDER BY population DESC LIMIT 10') as cursor:
             print('Most 10 populated cities:')
-
             async for row in cursor:
                 print(row)
         # Most 10 populated cities:
@@ -241,39 +64,38 @@ async def main():
         # ['Calcutta [Kolkata]', 4399819]
         # ['Wuhan', 4344600]
         # ['Harbin', 4289800]
-
+        print('-' * 20)
         # 10 most populated cities in 3 countries (with pagination and header row)
-        MOST_POPULATED_IN_3_COUNTRIES_QUERY = '''
+        most_populated_in_3_countries = '''
         SELECT country.name as country_name, city.name as city_name, MAX(city.population) AS max_pop FROM country
             JOIN city ON city.countrycode = country.code
             WHERE country.code IN ('USA','IND','CHN')
             GROUP BY country.name, city.name ORDER BY max_pop DESC LIMIT 10
         '''
 
-        async with client.sql(MOST_POPULATED_IN_3_COUNTRIES_QUERY, include_field_names=True) as cursor:
+        async with client.sql(most_populated_in_3_countries, include_field_names=True) as cursor:
             print('Most 10 populated cities in USA, India and China:')
-            print(await cursor.__anext__())
-            print('----------------------------------------')
+            table_str_pattern = '{:15}\t| {:20}\t| {}'
+            print(table_str_pattern.format(*await cursor.__anext__()))
+            print('*' * 50)
             async for row in cursor:
-                print(row)
+                print(table_str_pattern.format(*row))
         # Most 10 populated cities in USA, India and China:
-        # ['COUNTRY_NAME', 'CITY_NAME', 'MAX_POP']
-        # ----------------------------------------
-        # ['India', 'Mumbai (Bombay)', 10500000]
-        # ['China', 'Shanghai', 9696300]
-        # ['United States', 'New York', 8008278]
-        # ['China', 'Peking', 7472000]
-        # ['India', 'Delhi', 7206704]
-        # ['China', 'Chongqing', 6351600]
-        # ['China', 'Tianjin', 5286800]
-        # ['India', 'Calcutta [Kolkata]', 4399819]
-        # ['China', 'Wuhan', 4344600]
-        # ['China', 'Harbin', 4289800]
-
+        # COUNTRY_NAME   	| CITY_NAME           	| MAX_POP
+        # **************************************************
+        # India          	| Mumbai (Bombay)     	| 10500000
+        # China          	| Shanghai            	| 9696300
+        # United States  	| New York            	| 8008278
+        # China          	| Peking              	| 7472000
+        # India          	| Delhi               	| 7206704
+        # China          	| Chongqing           	| 6351600
+        # China          	| Tianjin             	| 5286800
+        # India          	| Calcutta [Kolkata]  	| 4399819
+        # China          	| Wuhan               	| 4344600
+        # China          	| Harbin              	| 4289800
+        print('-' * 20)
         # show city info
-        CITY_INFO_QUERY = '''SELECT * FROM City WHERE id = ?'''
-
-        async with client.sql(CITY_INFO_QUERY, query_args=[3802], include_field_names=True) as cursor:
+        async with client.sql('SELECT * FROM City WHERE id = ?', query_args=[3802], include_field_names=True) as cursor:
             field_names = await cursor.__anext__()
             field_data = await cursor.__anext__()
 
@@ -289,13 +111,9 @@ async def main():
 
         # clean up concurrently.
         await asyncio.gather(*[
-            client.sql(DROP_TABLE_QUERY.format(table_name)) for table_name in [
-                CITY_TABLE_NAME,
-                LANGUAGE_TABLE_NAME,
-                COUNTRY_TABLE_NAME,
-            ]
+            client.sql(Query.DROP_TABLE.format(table_name.value)) for table_name in TableNames
         ])
 
 
-loop = asyncio.get_event_loop()
-loop.run_until_complete(main())
+if __name__ == '__main__':
+    asyncio.run(main())
diff --git a/examples/binary_basics.py b/examples/binary_basics.py
index 50fa933..835cdc4 100644
--- a/examples/binary_basics.py
+++ b/examples/binary_basics.py
@@ -13,17 +13,15 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from collections import OrderedDict
-
 from pyignite import Client, GenericObjectMeta
 from pyignite.datatypes import String, IntObject
 
 
-class Person(metaclass=GenericObjectMeta, schema=OrderedDict([
-    ('first_name', String),
-    ('last_name', String),
-    ('age', IntObject),
-])):
+class Person(metaclass=GenericObjectMeta, schema={
+    'first_name': String,
+    'last_name': String,
+    'age': IntObject
+}):
     pass
 
 
@@ -50,3 +48,5 @@ with client.connect('localhost', 10800):
     client.register_binary_type(Person)
 
     Person = person.__class__
+    # cleanup
+    person_cache.destroy()
diff --git a/examples/create_binary.py b/examples/create_binary.py
index d2c2ce4..d0047f5 100644
--- a/examples/create_binary.py
+++ b/examples/create_binary.py
@@ -13,12 +13,19 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from collections import OrderedDict
-
 from pyignite import Client, GenericObjectMeta
 from pyignite.datatypes import DoubleObject, IntObject, String
 from pyignite.datatypes.prop_codes import PROP_NAME, PROP_SQL_SCHEMA, PROP_QUERY_ENTITIES
 
+
+class Student(
+    metaclass=GenericObjectMeta,
+    type_name='SQL_PUBLIC_STUDENT_TYPE',
+    schema={'NAME': String, 'LOGIN': String, 'AGE': IntObject, 'GPA': DoubleObject}
+):
+    pass
+
+
 client = Client()
 with client.connect('127.0.0.1', 10800):
     student_cache = client.create_cache({
@@ -61,18 +68,6 @@ with client.connect('127.0.0.1', 10800):
         ],
     })
 
-    class Student(
-        metaclass=GenericObjectMeta,
-        type_name='SQL_PUBLIC_STUDENT_TYPE',
-        schema=OrderedDict([
-            ('NAME', String),
-            ('LOGIN', String),
-            ('AGE', IntObject),
-            ('GPA', DoubleObject),
-        ])
-    ):
-        pass
-
     student_cache.put(
         1,
         Student(LOGIN='jdoe', NAME='John Doe', AGE=17, GPA=4.25),
diff --git a/examples/expiry_policy.py b/examples/expiry_policy.py
index 3dbe54b..8482e51 100644
--- a/examples/expiry_policy.py
+++ b/examples/expiry_policy.py
@@ -12,6 +12,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
 import asyncio
 import time
 from datetime import timedelta
@@ -22,7 +23,7 @@ from pyignite.datatypes.prop_codes import PROP_NAME, PROP_EXPIRY_POLICY
 from pyignite.exceptions import NotSupportedByClusterError
 
 
-def main():
+def sync_actions():
     print("Running sync ExpiryPolicy example.")
 
     client = Client()
@@ -63,7 +64,7 @@ def main():
             simple_cache.destroy()
 
 
-async def async_main():
+async def async_actions():
     print("Running async ExpiryPolicy example.")
 
     client = AioClient()
@@ -107,8 +108,24 @@ async def async_main():
         finally:
             await simple_cache.destroy()
 
+
 if __name__ == '__main__':
-    main()
+    sync_actions()
+    print('-' * 20)
+    asyncio.run(async_actions())
 
-    loop = asyncio.get_event_loop()
-    loop.run_until_complete(async_main())
+# Running sync ExpiryPolicy example.
+# Create cache with expiry policy.
+# key = 1, value = 1
+# key = 1, value = None
+# Create simple Cache and set TTL through `with_expire_policy`
+# key = 1, value = 1
+# key = 1, value = None
+# --------------------
+# Running async ExpiryPolicy example.
+# Create cache with expiry policy.
+# key = 1, value = 1
+# key = 1, value = None
+# Create simple Cache and set TTL through `with_expire_policy`
+# key = 1, value = 1
+# key = 1, value = None
diff --git a/examples/get_and_put_complex.py b/examples/get_and_put_complex.py
index cff0c2f..0938379 100644
--- a/examples/get_and_put_complex.py
+++ b/examples/get_and_put_complex.py
@@ -13,8 +13,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from collections import OrderedDict
-
 from pyignite import Client
 from pyignite.datatypes import CollectionObject, MapObject, ObjectArrayObject
 
@@ -23,19 +21,19 @@ client = Client()
 with client.connect('127.0.0.1', 10800):
     my_cache = client.get_or_create_cache('my cache')
 
-    value = OrderedDict([(1, 'test'), ('key', 2.0)])
+    value = {1: 'test', 'key': 2.0}
 
     # saving ordered dictionary
     type_id = MapObject.LINKED_HASH_MAP
     my_cache.put('my dict', (type_id, value))
     result = my_cache.get('my dict')
-    print(result)  # (2, OrderedDict([(1, 'test'), ('key', 2.0)]))
+    print(result)  # (2, {1: 'test', 'key': 2.0})
 
     # saving unordered dictionary
     type_id = MapObject.HASH_MAP
     my_cache.put('my dict', (type_id, value))
     result = my_cache.get('my dict')
-    print(result)  # (1, {'key': 2.0, 1: 'test'})
+    print(result)  # (1, {1: 'test', 'key': 2.0})
 
     type_id = CollectionObject.LINKED_LIST
     value = [1, '2', 3.0]
diff --git a/examples/helpers/converters.py b/examples/helpers/converters.py
new file mode 100644
index 0000000..4122c49
--- /dev/null
+++ b/examples/helpers/converters.py
@@ -0,0 +1,5 @@
+def obj_to_dict(obj):
+    result = {'type_name': obj.type_name}
+    for data in obj.schema:
+        result.update({data: getattr(obj, data)})
+    return result
diff --git a/examples/helpers/sql_helper.py b/examples/helpers/sql_helper.py
new file mode 100644
index 0000000..f13d2ed
--- /dev/null
+++ b/examples/helpers/sql_helper.py
@@ -0,0 +1,193 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from decimal import Decimal
+from enum import Enum
+
+
+class TableNames(Enum):
+    COUNTRY_TABLE_NAME = 'Country'
+    CITY_TABLE_NAME = 'City'
+    LANGUAGE_TABLE_NAME = 'CountryLanguage'
+
+
+class Query:
+    COUNTRY_CREATE_TABLE = '''CREATE TABLE Country (
+        Code CHAR(3) PRIMARY KEY,
+        Name CHAR(52),
+        Continent CHAR(50),
+        Region CHAR(26),
+        SurfaceArea DECIMAL(10,2),
+        IndepYear SMALLINT(6),
+        Population INT(11),
+        LifeExpectancy DECIMAL(3,1),
+        GNP DECIMAL(10,2),
+        GNPOld DECIMAL(10,2),
+        LocalName CHAR(45),
+        GovernmentForm CHAR(45),
+        HeadOfState CHAR(60),
+        Capital INT(11),
+        Code2 CHAR(2)
+    )'''
+
+    COUNTRY_INSERT = '''INSERT INTO Country(
+        Code, Name, Continent, Region,
+        SurfaceArea, IndepYear, Population,
+        LifeExpectancy, GNP, GNPOld,
+        LocalName, GovernmentForm, HeadOfState,
+        Capital, Code2
+    ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'''
+
+    CITY_CREATE_TABLE = '''CREATE TABLE City (
+        ID INT(11),
+        Name CHAR(35),
+        CountryCode CHAR(3),
+        District CHAR(20),
+        Population INT(11),
+        PRIMARY KEY (ID, CountryCode)
+    ) WITH "affinityKey=CountryCode"'''
+
+    CITY_CREATE_INDEX = 'CREATE INDEX idx_country_code ON city (CountryCode)'
+
+    CITY_INSERT = '''INSERT INTO City(
+        ID, Name, CountryCode, District, Population
+    ) VALUES (?, ?, ?, ?, ?)'''
+
+    LANGUAGE_CREATE_TABLE = '''CREATE TABLE CountryLanguage (
+        CountryCode CHAR(3),
+        Language CHAR(30),
+        IsOfficial BOOLEAN,
+        Percentage DECIMAL(4,1),
+        PRIMARY KEY (CountryCode, Language)
+    ) WITH "affinityKey=CountryCode"'''
+
+    LANGUAGE_CREATE_INDEX = 'CREATE INDEX idx_lang_country_code ON CountryLanguage (CountryCode)'
+
+    LANGUAGE_INSERT = '''INSERT INTO CountryLanguage(
+        CountryCode, Language, IsOfficial, Percentage
+    ) VALUES (?, ?, ?, ?)'''
+
+    DROP_TABLE = 'DROP TABLE {} IF EXISTS'
+
+
+class TestData:
+    COUNTRY = [
+        [
+            'USA', 'United States', 'North America', 'North America',
+            Decimal('9363520.00'), 1776, 278357000,
+            Decimal('77.1'), Decimal('8510700.00'), Decimal('8110900.00'),
+            'United States', 'Federal Republic', 'George W. Bush',
+            3813, 'US',
+        ],
+        [
+            'IND', 'India', 'Asia', 'Southern and Central Asia',
+            Decimal('3287263.00'), 1947, 1013662000,
+            Decimal('62.5'), Decimal('447114.00'), Decimal('430572.00'),
+            'Bharat/India', 'Federal Republic', 'Kocheril Raman Narayanan',
+            1109, 'IN',
+        ],
+        [
+            'CHN', 'China', 'Asia', 'Eastern Asia',
+            Decimal('9572900.00'), -1523, 1277558000,
+            Decimal('71.4'), Decimal('982268.00'), Decimal('917719.00'),
+            'Zhongquo', 'PeoplesRepublic', 'Jiang Zemin',
+            1891, 'CN',
+        ],
+    ]
+
+    CITY = [
+        [3793, 'New York', 'USA', 'New York', 8008278],
+        [3794, 'Los Angeles', 'USA', 'California', 3694820],
+        [3795, 'Chicago', 'USA', 'Illinois', 2896016],
+        [3796, 'Houston', 'USA', 'Texas', 1953631],
+        [3797, 'Philadelphia', 'USA', 'Pennsylvania', 1517550],
+        [3798, 'Phoenix', 'USA', 'Arizona', 1321045],
+        [3799, 'San Diego', 'USA', 'California', 1223400],
+        [3800, 'Dallas', 'USA', 'Texas', 1188580],
+        [3801, 'San Antonio', 'USA', 'Texas', 1144646],
+        [3802, 'Detroit', 'USA', 'Michigan', 951270],
+        [3803, 'San Jose', 'USA', 'California', 894943],
+        [3804, 'Indianapolis', 'USA', 'Indiana', 791926],
+        [3805, 'San Francisco', 'USA', 'California', 776733],
+        [1024, 'Mumbai (Bombay)', 'IND', 'Maharashtra', 10500000],
+        [1025, 'Delhi', 'IND', 'Delhi', 7206704],
+        [1026, 'Calcutta [Kolkata]', 'IND', 'West Bengali', 4399819],
+        [1027, 'Chennai (Madras)', 'IND', 'Tamil Nadu', 3841396],
+        [1028, 'Hyderabad', 'IND', 'Andhra Pradesh', 2964638],
+        [1029, 'Ahmedabad', 'IND', 'Gujarat', 2876710],
+        [1030, 'Bangalore', 'IND', 'Karnataka', 2660088],
+        [1031, 'Kanpur', 'IND', 'Uttar Pradesh', 1874409],
+        [1032, 'Nagpur', 'IND', 'Maharashtra', 1624752],
+        [1033, 'Lucknow', 'IND', 'Uttar Pradesh', 1619115],
+        [1034, 'Pune', 'IND', 'Maharashtra', 1566651],
+        [1035, 'Surat', 'IND', 'Gujarat', 1498817],
+        [1036, 'Jaipur', 'IND', 'Rajasthan', 1458483],
+        [1890, 'Shanghai', 'CHN', 'Shanghai', 9696300],
+        [1891, 'Peking', 'CHN', 'Peking', 7472000],
+        [1892, 'Chongqing', 'CHN', 'Chongqing', 6351600],
+        [1893, 'Tianjin', 'CHN', 'Tianjin', 5286800],
+        [1894, 'Wuhan', 'CHN', 'Hubei', 4344600],
+        [1895, 'Harbin', 'CHN', 'Heilongjiang', 4289800],
+        [1896, 'Shenyang', 'CHN', 'Liaoning', 4265200],
+        [1897, 'Kanton [Guangzhou]', 'CHN', 'Guangdong', 4256300],
+        [1898, 'Chengdu', 'CHN', 'Sichuan', 3361500],
+        [1899, 'Nanking [Nanjing]', 'CHN', 'Jiangsu', 2870300],
+        [1900, 'Changchun', 'CHN', 'Jilin', 2812000],
+        [1901, 'Xi´an', 'CHN', 'Shaanxi', 2761400],
+        [1902, 'Dalian', 'CHN', 'Liaoning', 2697000],
+        [1903, 'Qingdao', 'CHN', 'Shandong', 2596000],
+        [1904, 'Jinan', 'CHN', 'Shandong', 2278100],
+        [1905, 'Hangzhou', 'CHN', 'Zhejiang', 2190500],
+        [1906, 'Zhengzhou', 'CHN', 'Henan', 2107200],
+    ]
+
+    LANGUAGE = [
+        ['USA', 'Chinese', False, Decimal('0.6')],
+        ['USA', 'English', True, Decimal('86.2')],
+        ['USA', 'French', False, Decimal('0.7')],
+        ['USA', 'German', False, Decimal('0.7')],
+        ['USA', 'Italian', False, Decimal('0.6')],
+        ['USA', 'Japanese', False, Decimal('0.2')],
+        ['USA', 'Korean', False, Decimal('0.3')],
+        ['USA', 'Polish', False, Decimal('0.3')],
+        ['USA', 'Portuguese', False, Decimal('0.2')],
+        ['USA', 'Spanish', False, Decimal('7.5')],
+        ['USA', 'Tagalog', False, Decimal('0.4')],
+        ['USA', 'Vietnamese', False, Decimal('0.2')],
+        ['IND', 'Asami', False, Decimal('1.5')],
+        ['IND', 'Bengali', False, Decimal('8.2')],
+        ['IND', 'Gujarati', False, Decimal('4.8')],
+        ['IND', 'Hindi', True, Decimal('39.9')],
+        ['IND', 'Kannada', False, Decimal('3.9')],
+        ['IND', 'Malajalam', False, Decimal('3.6')],
+        ['IND', 'Marathi', False, Decimal('7.4')],
+        ['IND', 'Orija', False, Decimal('3.3')],
+        ['IND', 'Punjabi', False, Decimal('2.8')],
+        ['IND', 'Tamil', False, Decimal('6.3')],
+        ['IND', 'Telugu', False, Decimal('7.8')],
+        ['IND', 'Urdu', False, Decimal('5.1')],
+        ['CHN', 'Chinese', True, Decimal('92.0')],
+        ['CHN', 'Dong', False, Decimal('0.2')],
+        ['CHN', 'Hui', False, Decimal('0.8')],
+        ['CHN', 'Mantšu', False, Decimal('0.9')],
+        ['CHN', 'Miao', False, Decimal('0.7')],
+        ['CHN', 'Mongolian', False, Decimal('0.4')],
+        ['CHN', 'Puyi', False, Decimal('0.2')],
+        ['CHN', 'Tibetan', False, Decimal('0.4')],
+        ['CHN', 'Tujia', False, Decimal('0.5')],
+        ['CHN', 'Uighur', False, Decimal('0.6')],
+        ['CHN', 'Yi', False, Decimal('0.6')],
+        ['CHN', 'Zhuang', False, Decimal('1.4')],
+    ]
diff --git a/examples/migrate_binary.py b/examples/migrate_binary.py
index c22fa4f..5e414e8 100644
--- a/examples/migrate_binary.py
+++ b/examples/migrate_binary.py
@@ -13,76 +13,74 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from collections import OrderedDict
 from datetime import date
 from decimal import Decimal
+from pprint import pprint
 
+from helpers.converters import obj_to_dict
 from pyignite import Client, GenericObjectMeta
-from pyignite.datatypes import (
-    BoolObject, DateObject, DecimalObject, LongObject, String,
-)
-
+from pyignite.datatypes import BoolObject, DateObject, DecimalObject, LongObject, String
 
 # prepare old data
-old_schema = OrderedDict([
-    ('date', DateObject),
-    ('reported', BoolObject),
-    ('purpose', String),
-    ('sum', DecimalObject),
-    ('recipient', String),
-    ('cashier_id', LongObject),
-])
-
-old_data = [
-    (1, {
+old_schema = {'date': DateObject,
+              'reported': BoolObject,
+              'purpose': String,
+              'sum': DecimalObject,
+              'recipient': String,
+              'cashier_id': LongObject
+              }
+
+old_data = {
+    1: {
         'date': date(2017, 9, 21),
         'reported': True,
         'purpose': 'Praesent eget fermentum massa',
         'sum': Decimal('666.67'),
         'recipient': 'John Doe',
         'cashier_id': 8,
-    }),
-    (2, {
+    },
+    2: {
         'date': date(2017, 10, 11),
         'reported': True,
         'purpose': 'Proin in bibendum nulla',
         'sum': Decimal('333.33'),
         'recipient': 'Jane Roe',
         'cashier_id': 9,
-    }),
-    (3, {
+    },
+    3: {
         'date': date(2017, 10, 11),
         'reported': True,
         'purpose': 'Suspendisse nec dolor auctor, scelerisque ex eu, iaculis odio',
         'sum': Decimal('400.0'),
         'recipient': 'Jane Roe',
         'cashier_id': 8,
-    }),
-    (4, {
+    },
+    4: {
         'date': date(2017, 10, 24),
         'reported': False,
         'purpose': 'Quisque ut leo ligula',
         'sum': Decimal('1234.5'),
         'recipient': 'Joe Bloggs',
         'cashier_id': 10,
-    }),
-    (5, {
+    },
+    5: {
         'date': date(2017, 12, 1),
         'reported': True,
         'purpose': 'Quisque ut leo ligula',
         'sum': Decimal('800.0'),
         'recipient': 'Richard Public',
         'cashier_id': 12,
-    }),
-    (6, {
+    },
+    6: {
         'date': date(2017, 12, 1),
         'reported': True,
         'purpose': 'Aenean eget bibendum lorem, a luctus libero',
         'sum': Decimal('135.79'),
         'recipient': 'Joe Bloggs',
         'cashier_id': 10,
-    }),
-]
+    }
+}
+
 
 # - add `report_date`
 # - set `report_date` to the current date if `reported` is True, None if False
@@ -110,13 +108,14 @@ client = Client()
 with client.connect('127.0.0.1', 10800):
     accounting = client.get_or_create_cache('accounting')
 
-    for key, value in old_data:
-        accounting.put(key, ExpenseVoucher(**value))
+    for item, value in old_data.items():
+        print(item)
+        accounting.put(item, ExpenseVoucher(**value))
 
     data_classes = client.query_binary_type('ExpenseVoucher')
     print(data_classes)
     # {
-    #     -231598180: <class '__main__.ExpenseVoucher'>
+    #     {547629991: <class 'pygridgain.binary.ExpenseVoucher'>, -231598180: <class '__main__.ExpenseVoucher'>}
     # }
 
 s_id, data_class = data_classes.popitem()
@@ -142,16 +141,16 @@ def migrate(cache, data, new_class):
     """ Migrate given data pages. """
     for key, old_value in data:
         # read data
-        print(old_value)
-        # ExpenseVoucher(
-        #     date=datetime(2017, 9, 21, 0, 0),
-        #     reported=True,
-        #     purpose='Praesent eget fermentum massa',
-        #     sum=Decimal('666.67'),
-        #     recipient='John Doe',
-        #     cashier_id=8,
-        #     version=1
-        # )
+        print('Old value:')
+        pprint(obj_to_dict(old_value))
+        # Old value:
+        # {'cashier_id': 10,
+        #  'date': datetime.datetime(2017, 12, 1, 0, 0),
+        #  'purpose': 'Aenean eget bibendum lorem, a luctus libero',
+        #  'recipient': 'Joe Bloggs',
+        #  'reported': True,
+        #  'sum': Decimal('135.79'),
+        #  'type_name': 'ExpenseVoucher'}
 
         # create new binary object
         new_value = new_class()
@@ -169,16 +168,18 @@ def migrate(cache, data, new_class):
 
         # verify data
         verify = cache.get(key)
-        print(verify)
-        # ExpenseVoucherV2(
-        #     purpose='Praesent eget fermentum massa',
-        #     sum=Decimal('666.67'),
-        #     recipient='John Doe',
-        #     cashier_id=8,
-        #     expense_date=datetime(2017, 9, 21, 0, 0),
-        #     report_date=datetime(2018, 8, 29, 0, 0),
-        #     version=1,
-        # )
+        print('New value:')
+        pprint(obj_to_dict(verify))
+        # New value:
+        # {'cashier_id': 10,
+        #  'expense_date': datetime.datetime(2017, 12, 1, 0, 0),
+        #  'purpose': 'Aenean eget bibendum lorem, a luctus libero',
+        #  'recipient': 'Joe Bloggs',
+        #  'report_date': datetime.datetime(2022, 5, 6, 0, 0),
+        #  'sum': Decimal('135.79'),
+        #  'type_name': 'ExpenseVoucher'}
+
+        print('-' * 20)
 
 
 # migrate data
diff --git a/examples/read_binary.py b/examples/read_binary.py
index fe642d8..92404ca 100644
--- a/examples/read_binary.py
+++ b/examples/read_binary.py
@@ -13,279 +13,119 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from decimal import Decimal
+from pprint import pprint
 
+from helpers.converters import obj_to_dict
+from helpers.sql_helper import TableNames, Query, TestData
 from pyignite import Client
 from pyignite.datatypes.prop_codes import PROP_NAME, PROP_QUERY_ENTITIES
 
-
-COUNTRY_TABLE_NAME = 'Country'
-CITY_TABLE_NAME = 'City'
-LANGUAGE_TABLE_NAME = 'CountryLanguage'
-
-COUNTRY_CREATE_TABLE_QUERY = '''CREATE TABLE Country (
-    Code CHAR(3) PRIMARY KEY,
-    Name CHAR(52),
-    Continent CHAR(50),
-    Region CHAR(26),
-    SurfaceArea DECIMAL(10,2),
-    IndepYear SMALLINT(6),
-    Population INT(11),
-    LifeExpectancy DECIMAL(3,1),
-    GNP DECIMAL(10,2),
-    GNPOld DECIMAL(10,2),
-    LocalName CHAR(45),
-    GovernmentForm CHAR(45),
-    HeadOfState CHAR(60),
-    Capital INT(11),
-    Code2 CHAR(2)
-)'''
-
-COUNTRY_INSERT_QUERY = '''INSERT INTO Country(
-    Code, Name, Continent, Region,
-    SurfaceArea, IndepYear, Population,
-    LifeExpectancy, GNP, GNPOld,
-    LocalName, GovernmentForm, HeadOfState,
-    Capital, Code2
-) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'''
-
-CITY_CREATE_TABLE_QUERY = '''CREATE TABLE City (
-    ID INT(11),
-    Name CHAR(35),
-    CountryCode CHAR(3),
-    District CHAR(20),
-    Population INT(11),
-    PRIMARY KEY (ID, CountryCode)
-) WITH "affinityKey=CountryCode"'''
-
-CITY_CREATE_INDEX = '''
-CREATE INDEX idx_country_code ON city (CountryCode)'''
-
-CITY_INSERT_QUERY = '''INSERT INTO City(
-    ID, Name, CountryCode, District, Population
-) VALUES (?, ?, ?, ?, ?)'''
-
-LANGUAGE_CREATE_TABLE_QUERY = '''CREATE TABLE CountryLanguage (
-    CountryCode CHAR(3),
-    Language CHAR(30),
-    IsOfficial BOOLEAN,
-    Percentage DECIMAL(4,1),
-    PRIMARY KEY (CountryCode, Language)
-) WITH "affinityKey=CountryCode"'''
-
-LANGUAGE_CREATE_INDEX = '''
-CREATE INDEX idx_lang_country_code ON CountryLanguage (CountryCode)'''
-
-LANGUAGE_INSERT_QUERY = '''INSERT INTO CountryLanguage(
-    CountryCode, Language, IsOfficial, Percentage
-) VALUES (?, ?, ?, ?)'''
-
-DROP_TABLE_QUERY = '''DROP TABLE {} IF EXISTS'''
-
-COUNTRY_DATA = [
-    [
-        'USA', 'United States', 'North America', 'North America',
-        Decimal('9363520.00'), 1776, 278357000,
-        Decimal('77.1'), Decimal('8510700.00'), Decimal('8110900.00'),
-        'United States', 'Federal Republic', 'George W. Bush',
-        3813, 'US',
-    ],
-    [
-        'IND', 'India', 'Asia', 'Southern and Central Asia',
-        Decimal('3287263.00'), 1947, 1013662000,
-        Decimal('62.5'), Decimal('447114.00'), Decimal('430572.00'),
-        'Bharat/India', 'Federal Republic', 'Kocheril Raman Narayanan',
-        1109, 'IN',
-    ],
-    [
-        'CHN', 'China', 'Asia', 'Eastern Asia',
-        Decimal('9572900.00'), -1523, 1277558000,
-        Decimal('71.4'), Decimal('982268.00'), Decimal('917719.00'),
-        'Zhongquo', 'PeoplesRepublic', 'Jiang Zemin',
-        1891, 'CN',
-    ],
-]
-
-CITY_DATA = [
-    [3793, 'New York', 'USA', 'New York', 8008278],
-    [3794, 'Los Angeles', 'USA', 'California', 3694820],
-    [3795, 'Chicago', 'USA', 'Illinois', 2896016],
-    [3796, 'Houston', 'USA', 'Texas', 1953631],
-    [3797, 'Philadelphia', 'USA', 'Pennsylvania', 1517550],
-    [3798, 'Phoenix', 'USA', 'Arizona', 1321045],
-    [3799, 'San Diego', 'USA', 'California', 1223400],
-    [3800, 'Dallas', 'USA', 'Texas', 1188580],
-    [3801, 'San Antonio', 'USA', 'Texas', 1144646],
-    [3802, 'Detroit', 'USA', 'Michigan', 951270],
-    [3803, 'San Jose', 'USA', 'California', 894943],
-    [3804, 'Indianapolis', 'USA', 'Indiana', 791926],
-    [3805, 'San Francisco', 'USA', 'California', 776733],
-    [1024, 'Mumbai (Bombay)', 'IND', 'Maharashtra', 10500000],
-    [1025, 'Delhi', 'IND', 'Delhi', 7206704],
-    [1026, 'Calcutta [Kolkata]', 'IND', 'West Bengali', 4399819],
-    [1027, 'Chennai (Madras)', 'IND', 'Tamil Nadu', 3841396],
-    [1028, 'Hyderabad', 'IND', 'Andhra Pradesh', 2964638],
-    [1029, 'Ahmedabad', 'IND', 'Gujarat', 2876710],
-    [1030, 'Bangalore', 'IND', 'Karnataka', 2660088],
-    [1031, 'Kanpur', 'IND', 'Uttar Pradesh', 1874409],
-    [1032, 'Nagpur', 'IND', 'Maharashtra', 1624752],
-    [1033, 'Lucknow', 'IND', 'Uttar Pradesh', 1619115],
-    [1034, 'Pune', 'IND', 'Maharashtra', 1566651],
-    [1035, 'Surat', 'IND', 'Gujarat', 1498817],
-    [1036, 'Jaipur', 'IND', 'Rajasthan', 1458483],
-    [1890, 'Shanghai', 'CHN', 'Shanghai', 9696300],
-    [1891, 'Peking', 'CHN', 'Peking', 7472000],
-    [1892, 'Chongqing', 'CHN', 'Chongqing', 6351600],
-    [1893, 'Tianjin', 'CHN', 'Tianjin', 5286800],
-    [1894, 'Wuhan', 'CHN', 'Hubei', 4344600],
-    [1895, 'Harbin', 'CHN', 'Heilongjiang', 4289800],
-    [1896, 'Shenyang', 'CHN', 'Liaoning', 4265200],
-    [1897, 'Kanton [Guangzhou]', 'CHN', 'Guangdong', 4256300],
-    [1898, 'Chengdu', 'CHN', 'Sichuan', 3361500],
-    [1899, 'Nanking [Nanjing]', 'CHN', 'Jiangsu', 2870300],
-    [1900, 'Changchun', 'CHN', 'Jilin', 2812000],
-    [1901, 'Xi´an', 'CHN', 'Shaanxi', 2761400],
-    [1902, 'Dalian', 'CHN', 'Liaoning', 2697000],
-    [1903, 'Qingdao', 'CHN', 'Shandong', 2596000],
-    [1904, 'Jinan', 'CHN', 'Shandong', 2278100],
-    [1905, 'Hangzhou', 'CHN', 'Zhejiang', 2190500],
-    [1906, 'Zhengzhou', 'CHN', 'Henan', 2107200],
-]
-
-LANGUAGE_DATA = [
-    ['USA', 'Chinese', False, Decimal('0.6')],
-    ['USA', 'English', True, Decimal('86.2')],
-    ['USA', 'French', False, Decimal('0.7')],
-    ['USA', 'German', False, Decimal('0.7')],
-    ['USA', 'Italian', False, Decimal('0.6')],
-    ['USA', 'Japanese', False, Decimal('0.2')],
-    ['USA', 'Korean', False, Decimal('0.3')],
-    ['USA', 'Polish', False, Decimal('0.3')],
-    ['USA', 'Portuguese', False, Decimal('0.2')],
-    ['USA', 'Spanish', False, Decimal('7.5')],
-    ['USA', 'Tagalog', False, Decimal('0.4')],
-    ['USA', 'Vietnamese', False, Decimal('0.2')],
-    ['IND', 'Asami', False, Decimal('1.5')],
-    ['IND', 'Bengali', False, Decimal('8.2')],
-    ['IND', 'Gujarati', False, Decimal('4.8')],
-    ['IND', 'Hindi', True, Decimal('39.9')],
-    ['IND', 'Kannada', False, Decimal('3.9')],
-    ['IND', 'Malajalam', False, Decimal('3.6')],
-    ['IND', 'Marathi', False, Decimal('7.4')],
-    ['IND', 'Orija', False, Decimal('3.3')],
-    ['IND', 'Punjabi', False, Decimal('2.8')],
-    ['IND', 'Tamil', False, Decimal('6.3')],
-    ['IND', 'Telugu', False, Decimal('7.8')],
-    ['IND', 'Urdu', False, Decimal('5.1')],
-    ['CHN', 'Chinese', True, Decimal('92.0')],
-    ['CHN', 'Dong', False, Decimal('0.2')],
-    ['CHN', 'Hui', False, Decimal('0.8')],
-    ['CHN', 'Mantšu', False, Decimal('0.9')],
-    ['CHN', 'Miao', False, Decimal('0.7')],
-    ['CHN', 'Mongolian', False, Decimal('0.4')],
-    ['CHN', 'Puyi', False, Decimal('0.2')],
-    ['CHN', 'Tibetan', False, Decimal('0.4')],
-    ['CHN', 'Tujia', False, Decimal('0.5')],
-    ['CHN', 'Uighur', False, Decimal('0.6')],
-    ['CHN', 'Yi', False, Decimal('0.6')],
-    ['CHN', 'Zhuang', False, Decimal('1.4')],
-]
-
-
 # establish connection
 client = Client()
 with client.connect('127.0.0.1', 10800):
-
     # create tables
     for query in [
-        COUNTRY_CREATE_TABLE_QUERY,
-        CITY_CREATE_TABLE_QUERY,
-        LANGUAGE_CREATE_TABLE_QUERY,
+        Query.COUNTRY_CREATE_TABLE,
+        Query.CITY_CREATE_TABLE,
+        Query.LANGUAGE_CREATE_TABLE,
     ]:
         client.sql(query)
 
     # create indices
-    for query in [CITY_CREATE_INDEX, LANGUAGE_CREATE_INDEX]:
+    for query in [Query.CITY_CREATE_INDEX, Query.LANGUAGE_CREATE_INDEX]:
         client.sql(query)
 
     # load data
-    for row in COUNTRY_DATA:
-        client.sql(COUNTRY_INSERT_QUERY, query_args=row)
+    for row in TestData.COUNTRY:
+        client.sql(Query.COUNTRY_INSERT, query_args=row)
 
-    for row in CITY_DATA:
-        client.sql(CITY_INSERT_QUERY, query_args=row)
+    for row in TestData.CITY:
+        client.sql(Query.CITY_INSERT, query_args=row)
 
-    for row in LANGUAGE_DATA:
-        client.sql(LANGUAGE_INSERT_QUERY, query_args=row)
+    for row in TestData.LANGUAGE:
+        client.sql(Query.LANGUAGE_INSERT, query_args=row)
 
     # examine the storage
     result = client.get_cache_names()
-    print(result)
-    # [
-    #     'SQL_PUBLIC_CITY',
-    #     'SQL_PUBLIC_COUNTRY',
-    #     'PUBLIC',
-    #     'SQL_PUBLIC_COUNTRYLANGUAGE'
-    # ]
+    pprint(result)
+    # ['SQL_PUBLIC_CITY', 'SQL_PUBLIC_COUNTRY', 'SQL_PUBLIC_COUNTRYLANGUAGE']
 
     city_cache = client.get_or_create_cache('SQL_PUBLIC_CITY')
-    print(city_cache.settings[PROP_NAME])
+    pprint(city_cache.settings[PROP_NAME])
     # 'SQL_PUBLIC_CITY'
 
-    print(city_cache.settings[PROP_QUERY_ENTITIES])
-    # {
-    #     'key_type_name': (
-    #         'SQL_PUBLIC_CITY_9ac8e17a_2f99_45b7_958e_06da32882e9d_KEY'
-    #     ),
-    #     'value_type_name': (
-    #         'SQL_PUBLIC_CITY_9ac8e17a_2f99_45b7_958e_06da32882e9d'
-    #     ),
-    #     'table_name': 'CITY',
-    #     'query_fields': [
-    #         ...
-    #     ],
-    #     'field_name_aliases': [
-    #         ...
-    #     ],
-    #     'query_indexes': []
-    # }
-
+    pprint(city_cache.settings[PROP_QUERY_ENTITIES])
+    # [{'field_name_aliases': [{'alias': 'DISTRICT', 'field_name': 'DISTRICT'},
+    #                              {'alias': 'POPULATION', 'field_name': 'POPULATION'},
+    #                              {'alias': 'COUNTRYCODE', 'field_name': 'COUNTRYCODE'},
+    #                              {'alias': 'ID', 'field_name': 'ID'},
+    #                              {'alias': 'NAME', 'field_name': 'NAME'}],
+    #       'key_field_name': None,
+    #       'key_type_name': 'SQL_PUBLIC_CITY_081f37cc8ac72b10f08ab1273b744497_KEY',
+    #       'query_fields': [{'default_value': None,
+    #                         'is_key_field': True,
+    #                         'is_notnull_constraint_field': False,
+    #                         'name': 'ID',
+    #                         'precision': -1,
+    #                         'scale': -1,
+    #                         'type_name': 'java.lang.Integer'},
+    #                        {'default_value': None,
+    #                         'is_key_field': False,
+    #                         'is_notnull_constraint_field': False,
+    #                         'name': 'NAME',
+    #                         'precision': 35,
+    #                         'scale': -1,
+    #                         'type_name': 'java.lang.String'},
+    #                        {'default_value': None,
+    #                         'is_key_field': True,
+    #                         'is_notnull_constraint_field': False,
+    #                         'name': 'COUNTRYCODE',
+    #                         'precision': 3,
+    #                         'scale': -1,
+    #                         'type_name': 'java.lang.String'},
+    #                        {'default_value': None,
+    #                         'is_key_field': False,
+    #                         'is_notnull_constraint_field': False,
+    #                         'name': 'DISTRICT',
+    #                         'precision': 20,
+    #                         'scale': -1,
+    #                         'type_name': 'java.lang.String'},
+    #                        {'default_value': None,
+    #                         'is_key_field': False,
+    #                         'is_notnull_constraint_field': False,
+    #                         'name': 'POPULATION',
+    #                         'precision': -1,
+    #                         'scale': -1,
+    #                         'type_name': 'java.lang.Integer'}],
+    #       'query_indexes': [],
+    #       'table_name': 'CITY',
+    #       'value_field_name': None,
+    #       'value_type_name': 'SQL_PUBLIC_CITY_081f37cc8ac72b10f08ab1273b744497'}]
+
+    print('-' * 20)
     with city_cache.scan() as cursor:
-        print(next(cursor))
-    # (
-    #     SQL_PUBLIC_CITY_6fe650e1_700f_4e74_867d_58f52f433c43_KEY(
-    #         ID=1890,
-    #         COUNTRYCODE='CHN',
-    #         version=1
-    #     ),
-    #     SQL_PUBLIC_CITY_6fe650e1_700f_4e74_867d_58f52f433c43(
-    #         NAME='Shanghai',
-    #         DISTRICT='Shanghai',
-    #         POPULATION=9696300,
-    #         version=1
-    #     )
-    # )
-
+        for line in next(cursor):
+            pprint(obj_to_dict(line))
+    # {'COUNTRYCODE': 'USA',
+    #  'ID': 3793,
+    #  'type_name': 'SQL_PUBLIC_CITY_081f37cc8ac72b10f08ab1273b744497_KEY'}
+    # {'DISTRICT': 'New York',
+    #  'NAME': 'New York',
+    #  'POPULATION': 8008278,
+    #  'type_name': 'SQL_PUBLIC_CITY_081f37cc8ac72b10f08ab1273b744497'}
+
+    print('-' * 20)
     with client.sql('SELECT _KEY, _VAL FROM CITY WHERE ID = ?', query_args=[1890]) as cursor:
-        print(next(cursor))
-    # (
-    #     SQL_PUBLIC_CITY_6fe650e1_700f_4e74_867d_58f52f433c43_KEY(
-    #         ID=1890,
-    #         COUNTRYCODE='CHN',
-    #         version=1
-    #     ),
-    #     SQL_PUBLIC_CITY_6fe650e1_700f_4e74_867d_58f52f433c43(
-    #         NAME='Shanghai',
-    #         DISTRICT='Shanghai',
-    #         POPULATION=9696300,
-    #         version=1
-    #     )
-    # )
+        for line in next(cursor):
+            pprint(obj_to_dict(line))
+    # {'COUNTRYCODE': 'CHN',
+    #  'ID': 1890,
+    #  'type_name': 'SQL_PUBLIC_CITY_081f37cc8ac72b10f08ab1273b744497_KEY'}
+    # {'DISTRICT': 'Shanghai',
+    #  'NAME': 'Shanghai',
+    #  'POPULATION': 9696300,
+    #  'type_name': 'SQL_PUBLIC_CITY_081f37cc8ac72b10f08ab1273b744497'}
 
     # clean up
-    for table_name in [
-        CITY_TABLE_NAME,
-        LANGUAGE_TABLE_NAME,
-        COUNTRY_TABLE_NAME,
-    ]:
-        result = client.sql(DROP_TABLE_QUERY.format(table_name))
+    for table_name in TableNames:
+        result = client.sql(Query.DROP_TABLE.format(table_name.value))
diff --git a/examples/scans.py b/examples/scans.py
index eaafa6e..9346372 100644
--- a/examples/scans.py
+++ b/examples/scans.py
@@ -13,6 +13,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from pprint import pprint
+
 from pyignite import Client
 
 client = Client()
@@ -39,7 +41,7 @@ with client.connect('127.0.0.1', 10800):
     # 'key_12' 12
 
     with my_cache.scan() as cursor:
-        print(dict(cursor))
+        pprint(dict(cursor))
     # {
     #     'key_17': 17,
     #     'key_10': 10,
diff --git a/examples/sql.py b/examples/sql.py
index d81ff26..269b20b 100644
--- a/examples/sql.py
+++ b/examples/sql.py
@@ -13,215 +13,36 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from decimal import Decimal
-
+from helpers.sql_helper import TableNames, Query, TestData
 from pyignite import Client
 
-
-COUNTRY_TABLE_NAME = 'Country'
-CITY_TABLE_NAME = 'City'
-LANGUAGE_TABLE_NAME = 'CountryLanguage'
-
-COUNTRY_CREATE_TABLE_QUERY = '''CREATE TABLE Country (
-    Code CHAR(3) PRIMARY KEY,
-    Name CHAR(52),
-    Continent CHAR(50),
-    Region CHAR(26),
-    SurfaceArea DECIMAL(10,2),
-    IndepYear SMALLINT(6),
-    Population INT(11),
-    LifeExpectancy DECIMAL(3,1),
-    GNP DECIMAL(10,2),
-    GNPOld DECIMAL(10,2),
-    LocalName CHAR(45),
-    GovernmentForm CHAR(45),
-    HeadOfState CHAR(60),
-    Capital INT(11),
-    Code2 CHAR(2)
-)'''
-
-COUNTRY_INSERT_QUERY = '''INSERT INTO Country(
-    Code, Name, Continent, Region,
-    SurfaceArea, IndepYear, Population,
-    LifeExpectancy, GNP, GNPOld,
-    LocalName, GovernmentForm, HeadOfState,
-    Capital, Code2
-) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'''
-
-CITY_CREATE_TABLE_QUERY = '''CREATE TABLE City (
-    ID INT(11),
-    Name CHAR(35),
-    CountryCode CHAR(3),
-    District CHAR(20),
-    Population INT(11),
-    PRIMARY KEY (ID, CountryCode)
-) WITH "affinityKey=CountryCode"'''
-
-CITY_CREATE_INDEX = '''
-CREATE INDEX idx_country_code ON city (CountryCode)'''
-
-CITY_INSERT_QUERY = '''INSERT INTO City(
-    ID, Name, CountryCode, District, Population
-) VALUES (?, ?, ?, ?, ?)'''
-
-LANGUAGE_CREATE_TABLE_QUERY = '''CREATE TABLE CountryLanguage (
-    CountryCode CHAR(3),
-    Language CHAR(30),
-    IsOfficial BOOLEAN,
-    Percentage DECIMAL(4,1),
-    PRIMARY KEY (CountryCode, Language)
-) WITH "affinityKey=CountryCode"'''
-
-LANGUAGE_CREATE_INDEX = '''
-CREATE INDEX idx_lang_country_code ON CountryLanguage (CountryCode)'''
-
-LANGUAGE_INSERT_QUERY = '''INSERT INTO CountryLanguage(
-    CountryCode, Language, IsOfficial, Percentage
-) VALUES (?, ?, ?, ?)'''
-
-DROP_TABLE_QUERY = '''DROP TABLE {} IF EXISTS'''
-
-COUNTRY_DATA = [
-    [
-        'USA', 'United States', 'North America', 'North America',
-        Decimal('9363520.00'), 1776, 278357000,
-        Decimal('77.1'), Decimal('8510700.00'), Decimal('8110900.00'),
-        'United States', 'Federal Republic', 'George W. Bush',
-        3813, 'US',
-    ],
-    [
-        'IND', 'India', 'Asia', 'Southern and Central Asia',
-        Decimal('3287263.00'), 1947, 1013662000,
-        Decimal('62.5'), Decimal('447114.00'), Decimal('430572.00'),
-        'Bharat/India', 'Federal Republic', 'Kocheril Raman Narayanan',
-        1109, 'IN',
-    ],
-    [
-        'CHN', 'China', 'Asia', 'Eastern Asia',
-        Decimal('9572900.00'), -1523, 1277558000,
-        Decimal('71.4'), Decimal('982268.00'), Decimal('917719.00'),
-        'Zhongquo', 'PeoplesRepublic', 'Jiang Zemin',
-        1891, 'CN',
-    ],
-]
-
-CITY_DATA = [
-    [3793, 'New York', 'USA', 'New York', 8008278],
-    [3794, 'Los Angeles', 'USA', 'California', 3694820],
-    [3795, 'Chicago', 'USA', 'Illinois', 2896016],
-    [3796, 'Houston', 'USA', 'Texas', 1953631],
-    [3797, 'Philadelphia', 'USA', 'Pennsylvania', 1517550],
-    [3798, 'Phoenix', 'USA', 'Arizona', 1321045],
-    [3799, 'San Diego', 'USA', 'California', 1223400],
-    [3800, 'Dallas', 'USA', 'Texas', 1188580],
-    [3801, 'San Antonio', 'USA', 'Texas', 1144646],
-    [3802, 'Detroit', 'USA', 'Michigan', 951270],
-    [3803, 'San Jose', 'USA', 'California', 894943],
-    [3804, 'Indianapolis', 'USA', 'Indiana', 791926],
-    [3805, 'San Francisco', 'USA', 'California', 776733],
-    [1024, 'Mumbai (Bombay)', 'IND', 'Maharashtra', 10500000],
-    [1025, 'Delhi', 'IND', 'Delhi', 7206704],
-    [1026, 'Calcutta [Kolkata]', 'IND', 'West Bengali', 4399819],
-    [1027, 'Chennai (Madras)', 'IND', 'Tamil Nadu', 3841396],
-    [1028, 'Hyderabad', 'IND', 'Andhra Pradesh', 2964638],
-    [1029, 'Ahmedabad', 'IND', 'Gujarat', 2876710],
-    [1030, 'Bangalore', 'IND', 'Karnataka', 2660088],
-    [1031, 'Kanpur', 'IND', 'Uttar Pradesh', 1874409],
-    [1032, 'Nagpur', 'IND', 'Maharashtra', 1624752],
-    [1033, 'Lucknow', 'IND', 'Uttar Pradesh', 1619115],
-    [1034, 'Pune', 'IND', 'Maharashtra', 1566651],
-    [1035, 'Surat', 'IND', 'Gujarat', 1498817],
-    [1036, 'Jaipur', 'IND', 'Rajasthan', 1458483],
-    [1890, 'Shanghai', 'CHN', 'Shanghai', 9696300],
-    [1891, 'Peking', 'CHN', 'Peking', 7472000],
-    [1892, 'Chongqing', 'CHN', 'Chongqing', 6351600],
-    [1893, 'Tianjin', 'CHN', 'Tianjin', 5286800],
-    [1894, 'Wuhan', 'CHN', 'Hubei', 4344600],
-    [1895, 'Harbin', 'CHN', 'Heilongjiang', 4289800],
-    [1896, 'Shenyang', 'CHN', 'Liaoning', 4265200],
-    [1897, 'Kanton [Guangzhou]', 'CHN', 'Guangdong', 4256300],
-    [1898, 'Chengdu', 'CHN', 'Sichuan', 3361500],
-    [1899, 'Nanking [Nanjing]', 'CHN', 'Jiangsu', 2870300],
-    [1900, 'Changchun', 'CHN', 'Jilin', 2812000],
-    [1901, 'Xi´an', 'CHN', 'Shaanxi', 2761400],
-    [1902, 'Dalian', 'CHN', 'Liaoning', 2697000],
-    [1903, 'Qingdao', 'CHN', 'Shandong', 2596000],
-    [1904, 'Jinan', 'CHN', 'Shandong', 2278100],
-    [1905, 'Hangzhou', 'CHN', 'Zhejiang', 2190500],
-    [1906, 'Zhengzhou', 'CHN', 'Henan', 2107200],
-]
-
-LANGUAGE_DATA = [
-    ['USA', 'Chinese', False, Decimal('0.6')],
-    ['USA', 'English', True, Decimal('86.2')],
-    ['USA', 'French', False, Decimal('0.7')],
-    ['USA', 'German', False, Decimal('0.7')],
-    ['USA', 'Italian', False, Decimal('0.6')],
-    ['USA', 'Japanese', False, Decimal('0.2')],
-    ['USA', 'Korean', False, Decimal('0.3')],
-    ['USA', 'Polish', False, Decimal('0.3')],
-    ['USA', 'Portuguese', False, Decimal('0.2')],
-    ['USA', 'Spanish', False, Decimal('7.5')],
-    ['USA', 'Tagalog', False, Decimal('0.4')],
-    ['USA', 'Vietnamese', False, Decimal('0.2')],
-    ['IND', 'Asami', False, Decimal('1.5')],
-    ['IND', 'Bengali', False, Decimal('8.2')],
-    ['IND', 'Gujarati', False, Decimal('4.8')],
-    ['IND', 'Hindi', True, Decimal('39.9')],
-    ['IND', 'Kannada', False, Decimal('3.9')],
-    ['IND', 'Malajalam', False, Decimal('3.6')],
-    ['IND', 'Marathi', False, Decimal('7.4')],
-    ['IND', 'Orija', False, Decimal('3.3')],
-    ['IND', 'Punjabi', False, Decimal('2.8')],
-    ['IND', 'Tamil', False, Decimal('6.3')],
-    ['IND', 'Telugu', False, Decimal('7.8')],
-    ['IND', 'Urdu', False, Decimal('5.1')],
-    ['CHN', 'Chinese', True, Decimal('92.0')],
-    ['CHN', 'Dong', False, Decimal('0.2')],
-    ['CHN', 'Hui', False, Decimal('0.8')],
-    ['CHN', 'Mantšu', False, Decimal('0.9')],
-    ['CHN', 'Miao', False, Decimal('0.7')],
-    ['CHN', 'Mongolian', False, Decimal('0.4')],
-    ['CHN', 'Puyi', False, Decimal('0.2')],
-    ['CHN', 'Tibetan', False, Decimal('0.4')],
-    ['CHN', 'Tujia', False, Decimal('0.5')],
-    ['CHN', 'Uighur', False, Decimal('0.6')],
-    ['CHN', 'Yi', False, Decimal('0.6')],
-    ['CHN', 'Zhuang', False, Decimal('1.4')],
-]
-
-
 # establish connection
 client = Client()
 with client.connect('127.0.0.1', 10800):
-
     # create tables
     for query in [
-        COUNTRY_CREATE_TABLE_QUERY,
-        CITY_CREATE_TABLE_QUERY,
-        LANGUAGE_CREATE_TABLE_QUERY,
+        Query.COUNTRY_CREATE_TABLE,
+        Query.CITY_CREATE_TABLE,
+        Query.LANGUAGE_CREATE_TABLE,
     ]:
         client.sql(query)
 
     # create indices
-    for query in [CITY_CREATE_INDEX, LANGUAGE_CREATE_INDEX]:
+    for query in [Query.CITY_CREATE_INDEX, Query.LANGUAGE_CREATE_INDEX]:
         client.sql(query)
 
     # load data
-    for row in COUNTRY_DATA:
-        client.sql(COUNTRY_INSERT_QUERY, query_args=row)
+    for row in TestData.COUNTRY:
+        client.sql(Query.COUNTRY_INSERT, query_args=row)
 
-    for row in CITY_DATA:
-        client.sql(CITY_INSERT_QUERY, query_args=row)
+    for row in TestData.CITY:
+        client.sql(Query.CITY_INSERT, query_args=row)
 
-    for row in LANGUAGE_DATA:
-        client.sql(LANGUAGE_INSERT_QUERY, query_args=row)
+    for row in TestData.LANGUAGE:
+        client.sql(Query.LANGUAGE_INSERT, query_args=row)
 
     # 10 most populated cities (with pagination)
-    MOST_POPULATED_QUERY = '''
-    SELECT name, population FROM City ORDER BY population DESC LIMIT 10'''
-
-    with client.sql(MOST_POPULATED_QUERY) as cursor:
+    with client.sql('SELECT name, population FROM City ORDER BY population DESC LIMIT 10') as cursor:
         print('Most 10 populated cities:')
         for row in cursor:
             print(row)
@@ -236,45 +57,44 @@ with client.connect('127.0.0.1', 10800):
     # ['Calcutta [Kolkata]', 4399819]
     # ['Wuhan', 4344600]
     # ['Harbin', 4289800]
-
+    print('-' * 20)
     # 10 most populated cities in 3 countries (with pagination and header row)
-    MOST_POPULATED_IN_3_COUNTRIES_QUERY = '''
+    MOST_POPULATED_IN_3_COUNTRIES = '''
     SELECT country.name as country_name, city.name as city_name, MAX(city.population) AS max_pop FROM country
         JOIN city ON city.countrycode = country.code
         WHERE country.code IN ('USA','IND','CHN')
         GROUP BY country.name, city.name ORDER BY max_pop DESC LIMIT 10
     '''
 
-    with client.sql(MOST_POPULATED_IN_3_COUNTRIES_QUERY, include_field_names=True) as cursor:
+    with client.sql(MOST_POPULATED_IN_3_COUNTRIES, include_field_names=True) as cursor:
         print('Most 10 populated cities in USA, India and China:')
-        print(next(cursor))
-        print('----------------------------------------')
+        table_str_pattern = '{:15}\t| {:20}\t| {}'
+        print(table_str_pattern.format(*next(cursor)))
+        print('*' * 50)
         for row in cursor:
-            print(row)
+            print(table_str_pattern.format(*row))
     # Most 10 populated cities in USA, India and China:
-    # ['COUNTRY_NAME', 'CITY_NAME', 'MAX_POP']
-    # ----------------------------------------
-    # ['India', 'Mumbai (Bombay)', 10500000]
-    # ['China', 'Shanghai', 9696300]
-    # ['United States', 'New York', 8008278]
-    # ['China', 'Peking', 7472000]
-    # ['India', 'Delhi', 7206704]
-    # ['China', 'Chongqing', 6351600]
-    # ['China', 'Tianjin', 5286800]
-    # ['India', 'Calcutta [Kolkata]', 4399819]
-    # ['China', 'Wuhan', 4344600]
-    # ['China', 'Harbin', 4289800]
-
-    # show city info
-    CITY_INFO_QUERY = '''SELECT * FROM City WHERE id = ?'''
-
-    with client.sql(CITY_INFO_QUERY, query_args=[3802], include_field_names=True) as cursor:
+    # COUNTRY_NAME   	| CITY_NAME           	| MAX_POP
+    # **************************************************
+    # India          	| Mumbai (Bombay)     	| 10500000
+    # China          	| Shanghai            	| 9696300
+    # United States  	| New York            	| 8008278
+    # China          	| Peking              	| 7472000
+    # India          	| Delhi               	| 7206704
+    # China          	| Chongqing           	| 6351600
+    # China          	| Tianjin             	| 5286800
+    # India          	| Calcutta [Kolkata]  	| 4399819
+    # China          	| Wuhan               	| 4344600
+    # China          	| Harbin              	| 4289800
+    print('-' * 20)
+
+    # Show city info
+    with client.sql('SELECT * FROM City WHERE id = ?', query_args=[3802], include_field_names=True) as cursor:
         field_names = next(cursor)
-        field_data = list(*cursor)
-
+        field = list(*cursor)
         print('City info:')
-        for field_name, field_value in zip(field_names * len(field_data), field_data):
-            print('{}: {}'.format(field_name, field_value))
+        for field_name, field_value in zip(field_names * len(field), field):
+            print(f'{field_name}: {field_value}')
     # City info:
     # ID: 3802
     # NAME: Detroit
@@ -282,10 +102,6 @@ with client.connect('127.0.0.1', 10800):
     # DISTRICT: Michigan
     # POPULATION: 951270
 
-    # clean up
-    for table_name in [
-        CITY_TABLE_NAME,
-        LANGUAGE_TABLE_NAME,
-        COUNTRY_TABLE_NAME,
-    ]:
-        result = client.sql(DROP_TABLE_QUERY.format(table_name))
+    # Clean up
+    for table_name in TableNames:
+        result = client.sql(Query.DROP_TABLE.format(table_name.value))
diff --git a/examples/transactions.py b/examples/transactions.py
index 53e9c30..b4231fd 100644
--- a/examples/transactions.py
+++ b/examples/transactions.py
@@ -19,8 +19,8 @@ import time
 
 from pyignite import AioClient, Client
 from pyignite.datatypes import TransactionIsolation, TransactionConcurrency
-from pyignite.datatypes.prop_codes import PROP_CACHE_ATOMICITY_MODE, PROP_NAME
 from pyignite.datatypes.cache_config import CacheAtomicityMode
+from pyignite.datatypes.prop_codes import PROP_CACHE_ATOMICITY_MODE, PROP_NAME
 from pyignite.exceptions import CacheError
 
 
@@ -129,17 +129,20 @@ def sync_example():
         cache.destroy()
 
 
-if __name__ == '__main__':
+def check_is_transactions_supported():
     client = Client()
     with client.connect('127.0.0.1', 10800):
         if not client.protocol_context.is_transactions_supported():
             print("'Transactions' API is not supported by cluster. Finishing...")
             exit(0)
 
+
+if __name__ == '__main__':
+    check_is_transactions_supported()
+
     print("Starting sync example")
     sync_example()
 
     if sys.version_info >= (3, 7):
         print("Starting async example")
-        loop = asyncio.get_event_loop()
-        loop.run_until_complete(async_example())
+        asyncio.run(async_example())
diff --git a/examples/type_hints.py b/examples/type_hints.py
index 8d53bf9..f8adf70 100644
--- a/examples/type_hints.py
+++ b/examples/type_hints.py
@@ -18,7 +18,6 @@ from pyignite.datatypes import CharObject, ShortObject
 
 client = Client()
 with client.connect('127.0.0.1', 10800):
-
     my_cache = client.get_or_create_cache('my cache')
 
     my_cache.put('my key', 42)
@@ -43,7 +42,7 @@ with client.connect('127.0.0.1', 10800):
 
     # now let us delete both keys at once
     my_cache.remove_keys([
-        'a',                # a default type key
+        'a',  # a default type key
         ('a', CharObject),  # a key of type CharObject
     ])