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:41 UTC

[ignite-python-thin-client] branch ignite-17054 created (now 5b28e6c)

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

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


      at 5b28e6c  IGNITE-17054: Fix examples and documentation

This branch includes the following new commits:

     new 5b28e6c  IGNITE-17054: Fix examples and documentation

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



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

Posted by is...@apache.org.
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
     ])