clickhouse-driver 0.0.4__tar.gz → 0.2.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. clickhouse-driver-0.2.9/LICENSE +21 -0
  2. clickhouse-driver-0.2.9/MANIFEST.in +1 -0
  3. clickhouse-driver-0.2.9/PKG-INFO +193 -0
  4. clickhouse-driver-0.2.9/README.rst +155 -0
  5. clickhouse-driver-0.2.9/clickhouse_driver/__init__.py +9 -0
  6. clickhouse-driver-0.2.9/clickhouse_driver/block.py +227 -0
  7. {clickhouse-driver-0.0.4/src → clickhouse-driver-0.2.9/clickhouse_driver}/blockstreamprofileinfo.py +2 -1
  8. clickhouse-driver-0.2.9/clickhouse_driver/bufferedreader.c +17131 -0
  9. clickhouse-driver-0.2.9/clickhouse_driver/bufferedreader.pyx +255 -0
  10. clickhouse-driver-0.2.9/clickhouse_driver/bufferedwriter.c +16613 -0
  11. clickhouse-driver-0.2.9/clickhouse_driver/bufferedwriter.pyx +147 -0
  12. clickhouse-driver-0.2.9/clickhouse_driver/client.py +812 -0
  13. clickhouse-driver-0.2.9/clickhouse_driver/clientinfo.py +119 -0
  14. clickhouse-driver-0.2.9/clickhouse_driver/columns/arraycolumn.py +161 -0
  15. clickhouse-driver-0.2.9/clickhouse_driver/columns/base.py +221 -0
  16. clickhouse-driver-0.2.9/clickhouse_driver/columns/boolcolumn.py +7 -0
  17. clickhouse-driver-0.2.9/clickhouse_driver/columns/datecolumn.py +108 -0
  18. clickhouse-driver-0.2.9/clickhouse_driver/columns/datetimecolumn.py +203 -0
  19. clickhouse-driver-0.2.9/clickhouse_driver/columns/decimalcolumn.py +116 -0
  20. clickhouse-driver-0.2.9/clickhouse_driver/columns/enumcolumn.py +129 -0
  21. clickhouse-driver-0.2.9/clickhouse_driver/columns/exceptions.py +12 -0
  22. clickhouse-driver-0.2.9/clickhouse_driver/columns/floatcolumn.py +34 -0
  23. clickhouse-driver-0.2.9/clickhouse_driver/columns/intcolumn.py +157 -0
  24. clickhouse-driver-0.2.9/clickhouse_driver/columns/intervalcolumn.py +33 -0
  25. clickhouse-driver-0.2.9/clickhouse_driver/columns/ipcolumn.py +118 -0
  26. clickhouse-driver-0.2.9/clickhouse_driver/columns/jsoncolumn.py +37 -0
  27. clickhouse-driver-0.2.9/clickhouse_driver/columns/largeint.c +10957 -0
  28. clickhouse-driver-0.2.9/clickhouse_driver/columns/largeint.pyx +243 -0
  29. clickhouse-driver-0.2.9/clickhouse_driver/columns/lowcardinalitycolumn.py +142 -0
  30. clickhouse-driver-0.2.9/clickhouse_driver/columns/mapcolumn.py +73 -0
  31. clickhouse-driver-0.2.9/clickhouse_driver/columns/nestedcolumn.py +10 -0
  32. clickhouse-driver-0.2.9/clickhouse_driver/columns/nothingcolumn.py +13 -0
  33. clickhouse-driver-0.2.9/clickhouse_driver/columns/nullablecolumn.py +7 -0
  34. clickhouse-driver-0.2.9/clickhouse_driver/columns/nullcolumn.py +15 -0
  35. clickhouse-driver-0.2.9/clickhouse_driver/columns/numpy/base.py +47 -0
  36. clickhouse-driver-0.2.9/clickhouse_driver/columns/numpy/boolcolumn.py +8 -0
  37. clickhouse-driver-0.2.9/clickhouse_driver/columns/numpy/datecolumn.py +19 -0
  38. clickhouse-driver-0.2.9/clickhouse_driver/columns/numpy/datetimecolumn.py +146 -0
  39. clickhouse-driver-0.2.9/clickhouse_driver/columns/numpy/floatcolumn.py +24 -0
  40. clickhouse-driver-0.2.9/clickhouse_driver/columns/numpy/intcolumn.py +43 -0
  41. clickhouse-driver-0.2.9/clickhouse_driver/columns/numpy/lowcardinalitycolumn.py +96 -0
  42. clickhouse-driver-0.2.9/clickhouse_driver/columns/numpy/service.py +58 -0
  43. clickhouse-driver-0.2.9/clickhouse_driver/columns/numpy/stringcolumn.py +78 -0
  44. clickhouse-driver-0.2.9/clickhouse_driver/columns/numpy/tuplecolumn.py +37 -0
  45. clickhouse-driver-0.2.9/clickhouse_driver/columns/service.py +185 -0
  46. clickhouse-driver-0.2.9/clickhouse_driver/columns/simpleaggregatefunctioncolumn.py +7 -0
  47. clickhouse-driver-0.2.9/clickhouse_driver/columns/stringcolumn.py +73 -0
  48. clickhouse-driver-0.2.9/clickhouse_driver/columns/tuplecolumn.py +63 -0
  49. clickhouse-driver-0.2.9/clickhouse_driver/columns/util.py +61 -0
  50. clickhouse-driver-0.2.9/clickhouse_driver/columns/uuidcolumn.py +64 -0
  51. {clickhouse-driver-0.0.4/src → clickhouse-driver-0.2.9/clickhouse_driver}/compression/__init__.py +1 -4
  52. clickhouse-driver-0.2.9/clickhouse_driver/compression/base.py +87 -0
  53. clickhouse-driver-0.2.9/clickhouse_driver/compression/lz4.py +21 -0
  54. clickhouse-driver-0.2.9/clickhouse_driver/compression/zstd.py +20 -0
  55. clickhouse-driver-0.2.9/clickhouse_driver/connection.py +793 -0
  56. clickhouse-driver-0.2.9/clickhouse_driver/context.py +36 -0
  57. clickhouse-driver-0.2.9/clickhouse_driver/dbapi/__init__.py +62 -0
  58. clickhouse-driver-0.2.9/clickhouse_driver/dbapi/connection.py +99 -0
  59. clickhouse-driver-0.2.9/clickhouse_driver/dbapi/cursor.py +370 -0
  60. clickhouse-driver-0.2.9/clickhouse_driver/dbapi/errors.py +40 -0
  61. clickhouse-driver-0.2.9/clickhouse_driver/dbapi/extras.py +73 -0
  62. clickhouse-driver-0.2.9/clickhouse_driver/defines.py +58 -0
  63. clickhouse-driver-0.2.9/clickhouse_driver/errors.py +453 -0
  64. clickhouse-driver-0.2.9/clickhouse_driver/log.py +48 -0
  65. clickhouse-driver-0.2.9/clickhouse_driver/numpy/block.py +8 -0
  66. clickhouse-driver-0.2.9/clickhouse_driver/numpy/helpers.py +28 -0
  67. clickhouse-driver-0.2.9/clickhouse_driver/numpy/result.py +123 -0
  68. clickhouse-driver-0.2.9/clickhouse_driver/opentelemetry.py +43 -0
  69. clickhouse-driver-0.2.9/clickhouse_driver/progress.py +44 -0
  70. {clickhouse-driver-0.0.4/src → clickhouse-driver-0.2.9/clickhouse_driver}/protocol.py +41 -4
  71. clickhouse-driver-0.2.9/clickhouse_driver/reader.py +69 -0
  72. clickhouse-driver-0.2.9/clickhouse_driver/result.py +144 -0
  73. clickhouse-driver-0.2.9/clickhouse_driver/settings/available.py +405 -0
  74. clickhouse-driver-0.2.9/clickhouse_driver/settings/types.py +50 -0
  75. clickhouse-driver-0.2.9/clickhouse_driver/settings/writer.py +34 -0
  76. clickhouse-driver-0.2.9/clickhouse_driver/streams/__init__.py +0 -0
  77. {clickhouse-driver-0.0.4/src → clickhouse-driver-0.2.9/clickhouse_driver}/streams/compressed.py +18 -35
  78. clickhouse-driver-0.2.9/clickhouse_driver/streams/native.py +108 -0
  79. clickhouse-driver-0.2.9/clickhouse_driver/util/__init__.py +0 -0
  80. clickhouse-driver-0.2.9/clickhouse_driver/util/compat.py +39 -0
  81. clickhouse-driver-0.2.9/clickhouse_driver/util/escape.py +94 -0
  82. clickhouse-driver-0.2.9/clickhouse_driver/util/helpers.py +171 -0
  83. clickhouse-driver-0.2.9/clickhouse_driver/varint.c +8292 -0
  84. clickhouse-driver-0.2.9/clickhouse_driver/varint.pyx +68 -0
  85. {clickhouse-driver-0.0.4/src → clickhouse-driver-0.2.9/clickhouse_driver}/writer.py +10 -33
  86. clickhouse-driver-0.2.9/clickhouse_driver.egg-info/PKG-INFO +193 -0
  87. clickhouse-driver-0.2.9/clickhouse_driver.egg-info/SOURCES.txt +113 -0
  88. clickhouse-driver-0.2.9/clickhouse_driver.egg-info/requires.txt +19 -0
  89. {clickhouse-driver-0.0.4 → clickhouse-driver-0.2.9}/setup.cfg +11 -0
  90. clickhouse-driver-0.2.9/setup.py +139 -0
  91. clickhouse-driver-0.2.9/tests/test_blocks.py +247 -0
  92. clickhouse-driver-0.2.9/tests/test_buffered_reader.py +22 -0
  93. clickhouse-driver-0.2.9/tests/test_client.py +290 -0
  94. clickhouse-driver-0.2.9/tests/test_compression.py +103 -0
  95. clickhouse-driver-0.2.9/tests/test_connect.py +412 -0
  96. clickhouse-driver-0.2.9/tests/test_dbapi.py +496 -0
  97. clickhouse-driver-0.2.9/tests/test_errors.py +17 -0
  98. clickhouse-driver-0.2.9/tests/test_external_tables.py +36 -0
  99. clickhouse-driver-0.2.9/tests/test_insert.py +235 -0
  100. clickhouse-driver-0.2.9/tests/test_opentelemetry.py +89 -0
  101. clickhouse-driver-0.2.9/tests/test_query_info.py +164 -0
  102. clickhouse-driver-0.2.9/tests/test_settings.py +167 -0
  103. clickhouse-driver-0.2.9/tests/test_substitution.py +280 -0
  104. clickhouse-driver-0.2.9/tests/test_varint.py +19 -0
  105. clickhouse-driver-0.2.9/tests/testcase.py +131 -0
  106. clickhouse-driver-0.0.4/PKG-INFO +0 -203
  107. clickhouse-driver-0.0.4/README.rst +0 -178
  108. clickhouse-driver-0.0.4/clickhouse_driver.egg-info/PKG-INFO +0 -203
  109. clickhouse-driver-0.0.4/clickhouse_driver.egg-info/SOURCES.txt +0 -43
  110. clickhouse-driver-0.0.4/clickhouse_driver.egg-info/requires.txt +0 -14
  111. clickhouse-driver-0.0.4/setup.py +0 -80
  112. clickhouse-driver-0.0.4/src/block.py +0 -74
  113. clickhouse-driver-0.0.4/src/client.py +0 -111
  114. clickhouse-driver-0.0.4/src/clientinfo.py +0 -72
  115. clickhouse-driver-0.0.4/src/columns/arraycolumn.py +0 -128
  116. clickhouse-driver-0.0.4/src/columns/base.py +0 -50
  117. clickhouse-driver-0.0.4/src/columns/datecolumn.py +0 -21
  118. clickhouse-driver-0.0.4/src/columns/datetimecolumn.py +0 -22
  119. clickhouse-driver-0.0.4/src/columns/enumcolumn.py +0 -71
  120. clickhouse-driver-0.0.4/src/columns/floatcolumn.py +0 -33
  121. clickhouse-driver-0.0.4/src/columns/intcolumn.py +0 -75
  122. clickhouse-driver-0.0.4/src/columns/service.py +0 -56
  123. clickhouse-driver-0.0.4/src/columns/stringcolumn.py +0 -35
  124. clickhouse-driver-0.0.4/src/compression/base.py +0 -41
  125. clickhouse-driver-0.0.4/src/compression/lz4.py +0 -55
  126. clickhouse-driver-0.0.4/src/compression/quicklz.py +0 -60
  127. clickhouse-driver-0.0.4/src/compression/zstd.py +0 -51
  128. clickhouse-driver-0.0.4/src/connection.py +0 -381
  129. clickhouse-driver-0.0.4/src/defines.py +0 -24
  130. clickhouse-driver-0.0.4/src/errors.py +0 -106
  131. clickhouse-driver-0.0.4/src/progress.py +0 -19
  132. clickhouse-driver-0.0.4/src/reader.py +0 -101
  133. clickhouse-driver-0.0.4/src/streams/native.py +0 -77
  134. clickhouse-driver-0.0.4/src/util/tzinfo.py +0 -19
  135. {clickhouse-driver-0.0.4/src → clickhouse-driver-0.2.9/clickhouse_driver/columns}/__init__.py +0 -0
  136. {clickhouse-driver-0.0.4/src/columns → clickhouse-driver-0.2.9/clickhouse_driver/columns/numpy}/__init__.py +0 -0
  137. {clickhouse-driver-0.0.4/src → clickhouse-driver-0.2.9/clickhouse_driver}/compression/lz4hc.py +0 -0
  138. {clickhouse-driver-0.0.4/src/streams → clickhouse-driver-0.2.9/clickhouse_driver/numpy}/__init__.py +0 -0
  139. {clickhouse-driver-0.0.4/src → clickhouse-driver-0.2.9/clickhouse_driver}/queryprocessingstage.py +0 -0
  140. {clickhouse-driver-0.0.4/src → clickhouse-driver-0.2.9/clickhouse_driver}/readhelpers.py +0 -0
  141. {clickhouse-driver-0.0.4/src/util → clickhouse-driver-0.2.9/clickhouse_driver/settings}/__init__.py +0 -0
  142. {clickhouse-driver-0.0.4 → clickhouse-driver-0.2.9}/clickhouse_driver.egg-info/dependency_links.txt +0 -0
  143. {clickhouse-driver-0.0.4 → clickhouse-driver-0.2.9}/clickhouse_driver.egg-info/top_level.txt +0 -0
@@ -0,0 +1,21 @@
1
+ This is the MIT license: http://www.opensource.org/licenses/mit-license.php
2
+
3
+ Copyright (c) 2017 by Konstantin Lebedev.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ recursive-include clickhouse_driver *.pyx
@@ -0,0 +1,193 @@
1
+ Metadata-Version: 2.1
2
+ Name: clickhouse-driver
3
+ Version: 0.2.9
4
+ Summary: Python driver with native interface for ClickHouse
5
+ Home-page: https://github.com/mymarilyn/clickhouse-driver
6
+ Author: Konstantin Lebedev
7
+ Author-email: kostyan.lebedev@gmail.com
8
+ License: MIT
9
+ Project-URL: Documentation, https://clickhouse-driver.readthedocs.io
10
+ Project-URL: Changes, https://github.com/mymarilyn/clickhouse-driver/blob/master/CHANGELOG.md
11
+ Description: ClickHouse Python Driver
12
+ ========================
13
+
14
+ .. image:: https://img.shields.io/pypi/v/clickhouse-driver.svg
15
+ :target: https://pypi.org/project/clickhouse-driver
16
+
17
+ .. image:: https://coveralls.io/repos/github/mymarilyn/clickhouse-driver/badge.svg?branch=master
18
+ :target: https://coveralls.io/github/mymarilyn/clickhouse-driver?branch=master
19
+
20
+ .. image:: https://img.shields.io/pypi/l/clickhouse-driver.svg
21
+ :target: https://pypi.org/project/clickhouse-driver
22
+
23
+ .. image:: https://img.shields.io/pypi/pyversions/clickhouse-driver.svg
24
+ :target: https://pypi.org/project/clickhouse-driver
25
+
26
+ .. image:: https://img.shields.io/pypi/dm/clickhouse-driver.svg
27
+ :target: https://pypi.org/project/clickhouse-driver
28
+
29
+ .. image:: https://github.com/mymarilyn/clickhouse-driver/actions/workflows/actions.yml/badge.svg
30
+ :target: https://github.com/mymarilyn/clickhouse-driver/actions/workflows/actions.yml
31
+
32
+ ClickHouse Python Driver with native (TCP) interface support.
33
+
34
+ Asynchronous wrapper is available here: https://github.com/mymarilyn/aioch
35
+
36
+ Features
37
+ ========
38
+
39
+ - External data for query processing.
40
+
41
+ - Query settings.
42
+
43
+ - Compression support.
44
+
45
+ - TLS support.
46
+
47
+ - Types support:
48
+
49
+ * Float32/64
50
+ * [U]Int8/16/32/64/128/256
51
+ * Date/Date32/DateTime('timezone')/DateTime64('timezone')
52
+ * String/FixedString(N)
53
+ * Enum8/16
54
+ * Array(T)
55
+ * Nullable(T)
56
+ * Bool
57
+ * UUID
58
+ * Decimal
59
+ * IPv4/IPv6
60
+ * LowCardinality(T)
61
+ * SimpleAggregateFunction(F, T)
62
+ * Tuple(T1, T2, ...)
63
+ * Nested
64
+ * Map(key, value)
65
+
66
+ - Query progress information.
67
+
68
+ - Block by block results streaming.
69
+
70
+ - Reading query profile info.
71
+
72
+ - Receiving server logs.
73
+
74
+ - Multiple hosts support.
75
+
76
+ - Python DB API 2.0 specification support.
77
+
78
+ - Optional NumPy arrays support.
79
+
80
+ Documentation
81
+ =============
82
+
83
+ Documentation is available at https://clickhouse-driver.readthedocs.io.
84
+
85
+ Usage
86
+ =====
87
+
88
+ There are two ways to communicate with server:
89
+
90
+ - using pure Client;
91
+ - using DB API.
92
+
93
+ Pure Client example:
94
+
95
+ .. code-block:: python
96
+
97
+ >>> from clickhouse_driver import Client
98
+ >>>
99
+ >>> client = Client('localhost')
100
+ >>>
101
+ >>> client.execute('SHOW TABLES')
102
+ [('test',)]
103
+ >>> client.execute('DROP TABLE IF EXISTS test')
104
+ []
105
+ >>> client.execute('CREATE TABLE test (x Int32) ENGINE = Memory')
106
+ []
107
+ >>> client.execute(
108
+ ... 'INSERT INTO test (x) VALUES',
109
+ ... [{'x': 100}]
110
+ ... )
111
+ 1
112
+ >>> client.execute('INSERT INTO test (x) VALUES', [[200]])
113
+ 1
114
+ >>> client.execute(
115
+ ... 'INSERT INTO test (x) '
116
+ ... 'SELECT * FROM system.numbers LIMIT %(limit)s',
117
+ ... {'limit': 3}
118
+ ... )
119
+ []
120
+ >>> client.execute('SELECT sum(x) FROM test')
121
+ [(303,)]
122
+
123
+ DB API example:
124
+
125
+ .. code-block:: python
126
+
127
+ >>> from clickhouse_driver import connect
128
+ >>>
129
+ >>> conn = connect('clickhouse://localhost')
130
+ >>> cursor = conn.cursor()
131
+ >>>
132
+ >>> cursor.execute('SHOW TABLES')
133
+ >>> cursor.fetchall()
134
+ [('test',)]
135
+ >>> cursor.execute('DROP TABLE IF EXISTS test')
136
+ >>> cursor.fetchall()
137
+ []
138
+ >>> cursor.execute('CREATE TABLE test (x Int32) ENGINE = Memory')
139
+ >>> cursor.fetchall()
140
+ []
141
+ >>> cursor.executemany(
142
+ ... 'INSERT INTO test (x) VALUES',
143
+ ... [{'x': 100}]
144
+ ... )
145
+ >>> cursor.rowcount
146
+ 1
147
+ >>> cursor.executemany('INSERT INTO test (x) VALUES', [[200]])
148
+ >>> cursor.rowcount
149
+ 1
150
+ >>> cursor.execute(
151
+ ... 'INSERT INTO test (x) '
152
+ ... 'SELECT * FROM system.numbers LIMIT %(limit)s',
153
+ ... {'limit': 3}
154
+ ... )
155
+ >>> cursor.rowcount
156
+ 0
157
+ >>> cursor.execute('SELECT sum(x) FROM test')
158
+ >>> cursor.fetchall()
159
+ [(303,)]
160
+
161
+ License
162
+ =======
163
+
164
+ ClickHouse Python Driver is distributed under the `MIT license
165
+ <http://www.opensource.org/licenses/mit-license.php>`_.
166
+
167
+ Keywords: ClickHouse db database cloud analytics
168
+ Platform: UNKNOWN
169
+ Classifier: Development Status :: 4 - Beta
170
+ Classifier: Environment :: Console
171
+ Classifier: Intended Audience :: Developers
172
+ Classifier: Intended Audience :: Information Technology
173
+ Classifier: License :: OSI Approved :: MIT License
174
+ Classifier: Operating System :: OS Independent
175
+ Classifier: Programming Language :: SQL
176
+ Classifier: Programming Language :: Python :: 3
177
+ Classifier: Programming Language :: Python :: 3.7
178
+ Classifier: Programming Language :: Python :: 3.8
179
+ Classifier: Programming Language :: Python :: 3.9
180
+ Classifier: Programming Language :: Python :: 3.10
181
+ Classifier: Programming Language :: Python :: 3.11
182
+ Classifier: Programming Language :: Python :: 3.12
183
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
184
+ Classifier: Topic :: Database
185
+ Classifier: Topic :: Software Development
186
+ Classifier: Topic :: Software Development :: Libraries
187
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
188
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
189
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
190
+ Requires-Python: >=3.7, <4
191
+ Provides-Extra: lz4
192
+ Provides-Extra: zstd
193
+ Provides-Extra: numpy
@@ -0,0 +1,155 @@
1
+ ClickHouse Python Driver
2
+ ========================
3
+
4
+ .. image:: https://img.shields.io/pypi/v/clickhouse-driver.svg
5
+ :target: https://pypi.org/project/clickhouse-driver
6
+
7
+ .. image:: https://coveralls.io/repos/github/mymarilyn/clickhouse-driver/badge.svg?branch=master
8
+ :target: https://coveralls.io/github/mymarilyn/clickhouse-driver?branch=master
9
+
10
+ .. image:: https://img.shields.io/pypi/l/clickhouse-driver.svg
11
+ :target: https://pypi.org/project/clickhouse-driver
12
+
13
+ .. image:: https://img.shields.io/pypi/pyversions/clickhouse-driver.svg
14
+ :target: https://pypi.org/project/clickhouse-driver
15
+
16
+ .. image:: https://img.shields.io/pypi/dm/clickhouse-driver.svg
17
+ :target: https://pypi.org/project/clickhouse-driver
18
+
19
+ .. image:: https://github.com/mymarilyn/clickhouse-driver/actions/workflows/actions.yml/badge.svg
20
+ :target: https://github.com/mymarilyn/clickhouse-driver/actions/workflows/actions.yml
21
+
22
+ ClickHouse Python Driver with native (TCP) interface support.
23
+
24
+ Asynchronous wrapper is available here: https://github.com/mymarilyn/aioch
25
+
26
+ Features
27
+ ========
28
+
29
+ - External data for query processing.
30
+
31
+ - Query settings.
32
+
33
+ - Compression support.
34
+
35
+ - TLS support.
36
+
37
+ - Types support:
38
+
39
+ * Float32/64
40
+ * [U]Int8/16/32/64/128/256
41
+ * Date/Date32/DateTime('timezone')/DateTime64('timezone')
42
+ * String/FixedString(N)
43
+ * Enum8/16
44
+ * Array(T)
45
+ * Nullable(T)
46
+ * Bool
47
+ * UUID
48
+ * Decimal
49
+ * IPv4/IPv6
50
+ * LowCardinality(T)
51
+ * SimpleAggregateFunction(F, T)
52
+ * Tuple(T1, T2, ...)
53
+ * Nested
54
+ * Map(key, value)
55
+
56
+ - Query progress information.
57
+
58
+ - Block by block results streaming.
59
+
60
+ - Reading query profile info.
61
+
62
+ - Receiving server logs.
63
+
64
+ - Multiple hosts support.
65
+
66
+ - Python DB API 2.0 specification support.
67
+
68
+ - Optional NumPy arrays support.
69
+
70
+ Documentation
71
+ =============
72
+
73
+ Documentation is available at https://clickhouse-driver.readthedocs.io.
74
+
75
+ Usage
76
+ =====
77
+
78
+ There are two ways to communicate with server:
79
+
80
+ - using pure Client;
81
+ - using DB API.
82
+
83
+ Pure Client example:
84
+
85
+ .. code-block:: python
86
+
87
+ >>> from clickhouse_driver import Client
88
+ >>>
89
+ >>> client = Client('localhost')
90
+ >>>
91
+ >>> client.execute('SHOW TABLES')
92
+ [('test',)]
93
+ >>> client.execute('DROP TABLE IF EXISTS test')
94
+ []
95
+ >>> client.execute('CREATE TABLE test (x Int32) ENGINE = Memory')
96
+ []
97
+ >>> client.execute(
98
+ ... 'INSERT INTO test (x) VALUES',
99
+ ... [{'x': 100}]
100
+ ... )
101
+ 1
102
+ >>> client.execute('INSERT INTO test (x) VALUES', [[200]])
103
+ 1
104
+ >>> client.execute(
105
+ ... 'INSERT INTO test (x) '
106
+ ... 'SELECT * FROM system.numbers LIMIT %(limit)s',
107
+ ... {'limit': 3}
108
+ ... )
109
+ []
110
+ >>> client.execute('SELECT sum(x) FROM test')
111
+ [(303,)]
112
+
113
+ DB API example:
114
+
115
+ .. code-block:: python
116
+
117
+ >>> from clickhouse_driver import connect
118
+ >>>
119
+ >>> conn = connect('clickhouse://localhost')
120
+ >>> cursor = conn.cursor()
121
+ >>>
122
+ >>> cursor.execute('SHOW TABLES')
123
+ >>> cursor.fetchall()
124
+ [('test',)]
125
+ >>> cursor.execute('DROP TABLE IF EXISTS test')
126
+ >>> cursor.fetchall()
127
+ []
128
+ >>> cursor.execute('CREATE TABLE test (x Int32) ENGINE = Memory')
129
+ >>> cursor.fetchall()
130
+ []
131
+ >>> cursor.executemany(
132
+ ... 'INSERT INTO test (x) VALUES',
133
+ ... [{'x': 100}]
134
+ ... )
135
+ >>> cursor.rowcount
136
+ 1
137
+ >>> cursor.executemany('INSERT INTO test (x) VALUES', [[200]])
138
+ >>> cursor.rowcount
139
+ 1
140
+ >>> cursor.execute(
141
+ ... 'INSERT INTO test (x) '
142
+ ... 'SELECT * FROM system.numbers LIMIT %(limit)s',
143
+ ... {'limit': 3}
144
+ ... )
145
+ >>> cursor.rowcount
146
+ 0
147
+ >>> cursor.execute('SELECT sum(x) FROM test')
148
+ >>> cursor.fetchall()
149
+ [(303,)]
150
+
151
+ License
152
+ =======
153
+
154
+ ClickHouse Python Driver is distributed under the `MIT license
155
+ <http://www.opensource.org/licenses/mit-license.php>`_.
@@ -0,0 +1,9 @@
1
+
2
+ from .client import Client
3
+ from .dbapi import connect
4
+
5
+
6
+ VERSION = (0, 2, 9)
7
+ __version__ = '.'.join(str(x) for x in VERSION)
8
+
9
+ __all__ = ['Client', 'connect']
@@ -0,0 +1,227 @@
1
+ from .columns.util import get_inner_spec, get_inner_columns_with_types
2
+ from .reader import read_varint, read_binary_uint8, read_binary_int32
3
+ from .varint import write_varint
4
+ from .writer import write_binary_uint8, write_binary_int32
5
+
6
+
7
+ class BlockInfo(object):
8
+ is_overflows = False
9
+ bucket_num = -1
10
+
11
+ def write(self, buf):
12
+ # Set of pairs (`FIELD_NUM`, value) in binary form. Then 0.
13
+ write_varint(1, buf)
14
+ write_binary_uint8(self.is_overflows, buf)
15
+
16
+ write_varint(2, buf)
17
+ write_binary_int32(self.bucket_num, buf)
18
+
19
+ write_varint(0, buf)
20
+
21
+ def read(self, buf):
22
+ while True:
23
+ field_num = read_varint(buf)
24
+ if not field_num:
25
+ break
26
+
27
+ if field_num == 1:
28
+ self.is_overflows = bool(read_binary_uint8(buf))
29
+
30
+ elif field_num == 2:
31
+ self.bucket_num = read_binary_int32(buf)
32
+
33
+
34
+ class BaseBlock(object):
35
+ def __init__(self, columns_with_types=None, data=None,
36
+ info=None, types_check=False):
37
+ self.columns_with_types = columns_with_types or []
38
+ self.types_check = types_check
39
+ self.info = info or BlockInfo()
40
+ self.data = self.normalize(data or [])
41
+
42
+ super(BaseBlock, self).__init__()
43
+
44
+ def normalize(self, data):
45
+ return data
46
+
47
+ @property
48
+ def num_columns(self):
49
+ raise NotImplementedError
50
+
51
+ @property
52
+ def num_rows(self):
53
+ raise NotImplementedError
54
+
55
+ def get_columns(self):
56
+ raise NotImplementedError
57
+
58
+ def get_rows(self):
59
+ raise NotImplementedError
60
+
61
+ def get_column_by_index(self, index):
62
+ raise NotImplementedError
63
+
64
+ def transposed(self):
65
+ return list(zip(*self.data))
66
+
67
+
68
+ class ColumnOrientedBlock(BaseBlock):
69
+ def normalize(self, data):
70
+ if not data:
71
+ return []
72
+
73
+ self._check_number_of_columns(data)
74
+ self._check_all_columns_equal_length(data)
75
+ return data
76
+
77
+ @property
78
+ def num_columns(self):
79
+ return len(self.data)
80
+
81
+ @property
82
+ def num_rows(self):
83
+ return len(self.data[0]) if self.num_columns else 0
84
+
85
+ def get_columns(self):
86
+ return self.data
87
+
88
+ def get_rows(self):
89
+ return self.transposed()
90
+
91
+ def get_column_by_index(self, index):
92
+ return self.data[index]
93
+
94
+ def _check_number_of_columns(self, data):
95
+ expected_row_len = len(self.columns_with_types)
96
+
97
+ got = len(data)
98
+ if expected_row_len != got:
99
+ msg = 'Expected {} columns, got {}'.format(expected_row_len, got)
100
+ raise ValueError(msg)
101
+
102
+ def _check_all_columns_equal_length(self, data):
103
+ expected = len(data[0])
104
+
105
+ for column in data:
106
+ got = len(column)
107
+ if got != expected:
108
+ msg = 'Expected {} rows, got {}'.format(expected, got)
109
+ raise ValueError(msg)
110
+
111
+
112
+ class RowOrientedBlock(BaseBlock):
113
+ dict_row_types = (dict, )
114
+ tuple_row_types = (list, tuple)
115
+ supported_row_types = dict_row_types + tuple_row_types
116
+
117
+ def normalize(self, data):
118
+ if not data:
119
+ return []
120
+
121
+ # Guessing about whole data format by first row.
122
+ first_row = data[0]
123
+
124
+ if self.types_check:
125
+ self._check_row_type(first_row)
126
+
127
+ if isinstance(first_row, dict):
128
+ self._mutate_dicts_to_rows(data)
129
+ else:
130
+ self._check_rows(data)
131
+
132
+ return data
133
+
134
+ @property
135
+ def num_columns(self):
136
+ if self.columns_with_types is not None:
137
+ return len(self.columns_with_types)
138
+
139
+ return len(self.data[0]) if self.num_rows else 0
140
+
141
+ @property
142
+ def num_rows(self):
143
+ return len(self.data)
144
+
145
+ def get_columns(self):
146
+ return self.transposed()
147
+
148
+ def get_rows(self):
149
+ return self.data
150
+
151
+ def get_column_by_index(self, index):
152
+ return [row[index] for row in self.data]
153
+
154
+ def _mutate_dicts_to_rows(self, data):
155
+ check_row_type = False
156
+ if self.types_check:
157
+ check_row_type = self._check_dict_row_type
158
+
159
+ return self._pure_mutate_dicts_to_rows(
160
+ data,
161
+ self.columns_with_types,
162
+ check_row_type,
163
+ )
164
+
165
+ def _pure_mutate_dicts_to_rows(
166
+ self,
167
+ data,
168
+ columns_with_types,
169
+ check_row_type,
170
+ ):
171
+ columns_with_cwt = []
172
+ for name, type_ in columns_with_types:
173
+ cwt = None
174
+ if type_.startswith('Nested'):
175
+ inner_spec = get_inner_spec('Nested', type_)
176
+ cwt = get_inner_columns_with_types(inner_spec)
177
+ columns_with_cwt.append((name, cwt))
178
+
179
+ for i, row in enumerate(data):
180
+ if check_row_type:
181
+ check_row_type(row)
182
+
183
+ new_data = []
184
+ for name, cwt in columns_with_cwt:
185
+ if cwt is None:
186
+ new_data.append(row[name])
187
+ else:
188
+ new_data.append(self._pure_mutate_dicts_to_rows(
189
+ row[name], cwt, check_row_type
190
+ ))
191
+ data[i] = new_data
192
+ # return for recursion
193
+ return data
194
+
195
+ def _check_rows(self, data):
196
+ expected_row_len = len(self.columns_with_types)
197
+
198
+ got = len(data[0])
199
+ if expected_row_len != got:
200
+ msg = 'Expected {} columns, got {}'.format(expected_row_len, got)
201
+ raise ValueError(msg)
202
+
203
+ if self.types_check:
204
+ check_row_type = self._check_tuple_row_type
205
+ for row in data:
206
+ check_row_type(row)
207
+
208
+ def _check_row_type(self, row):
209
+ if not isinstance(row, self.supported_row_types):
210
+ raise TypeError(
211
+ 'Unsupported row type: {}. dict, list or tuple is expected.'
212
+ .format(type(row))
213
+ )
214
+
215
+ def _check_tuple_row_type(self, row):
216
+ if not isinstance(row, self.tuple_row_types):
217
+ raise TypeError(
218
+ 'Unsupported row type: {}. list or tuple is expected.'
219
+ .format(type(row))
220
+ )
221
+
222
+ def _check_dict_row_type(self, row):
223
+ if not isinstance(row, self.dict_row_types):
224
+ raise TypeError(
225
+ 'Unsupported row type: {}. dict is expected.'
226
+ .format(type(row))
227
+ )
@@ -1,4 +1,5 @@
1
- from .reader import read_varint, read_binary_uint8
1
+ from .reader import read_binary_uint8
2
+ from .varint import read_varint
2
3
 
3
4
 
4
5
  class BlockStreamProfileInfo(object):