clickhouse-driver 0.2.1__cp39-cp39-win_amd64.whl → 0.2.8__cp39-cp39-win_amd64.whl
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.
- clickhouse_driver/__init__.py +9 -9
- clickhouse_driver/block.py +227 -195
- clickhouse_driver/blockstreamprofileinfo.py +22 -22
- clickhouse_driver/bufferedreader.cp39-win_amd64.pyd +0 -0
- clickhouse_driver/bufferedwriter.cp39-win_amd64.pyd +0 -0
- clickhouse_driver/client.py +896 -666
- clickhouse_driver/clientinfo.py +119 -80
- clickhouse_driver/columns/arraycolumn.py +161 -150
- clickhouse_driver/columns/base.py +221 -147
- clickhouse_driver/columns/boolcolumn.py +7 -0
- clickhouse_driver/columns/datecolumn.py +108 -49
- clickhouse_driver/columns/datetimecolumn.py +202 -207
- clickhouse_driver/columns/decimalcolumn.py +116 -118
- clickhouse_driver/columns/enumcolumn.py +119 -119
- clickhouse_driver/columns/exceptions.py +12 -12
- clickhouse_driver/columns/floatcolumn.py +34 -34
- clickhouse_driver/columns/intcolumn.py +157 -157
- clickhouse_driver/columns/intervalcolumn.py +33 -33
- clickhouse_driver/columns/ipcolumn.py +118 -118
- clickhouse_driver/columns/jsoncolumn.py +37 -0
- clickhouse_driver/columns/largeint.cp39-win_amd64.pyd +0 -0
- clickhouse_driver/columns/lowcardinalitycolumn.py +142 -123
- clickhouse_driver/columns/mapcolumn.py +73 -58
- clickhouse_driver/columns/nestedcolumn.py +10 -0
- clickhouse_driver/columns/nothingcolumn.py +13 -13
- clickhouse_driver/columns/nullablecolumn.py +7 -7
- clickhouse_driver/columns/nullcolumn.py +15 -15
- clickhouse_driver/columns/numpy/base.py +47 -14
- clickhouse_driver/columns/numpy/boolcolumn.py +8 -0
- clickhouse_driver/columns/numpy/datecolumn.py +19 -12
- clickhouse_driver/columns/numpy/datetimecolumn.py +143 -145
- clickhouse_driver/columns/numpy/floatcolumn.py +24 -13
- clickhouse_driver/columns/numpy/intcolumn.py +43 -43
- clickhouse_driver/columns/numpy/lowcardinalitycolumn.py +96 -83
- clickhouse_driver/columns/numpy/service.py +58 -80
- clickhouse_driver/columns/numpy/stringcolumn.py +78 -76
- clickhouse_driver/columns/numpy/tuplecolumn.py +37 -0
- clickhouse_driver/columns/service.py +185 -131
- clickhouse_driver/columns/simpleaggregatefunctioncolumn.py +7 -7
- clickhouse_driver/columns/stringcolumn.py +73 -73
- clickhouse_driver/columns/tuplecolumn.py +63 -65
- clickhouse_driver/columns/util.py +60 -0
- clickhouse_driver/columns/uuidcolumn.py +64 -64
- clickhouse_driver/compression/__init__.py +28 -28
- clickhouse_driver/compression/base.py +87 -52
- clickhouse_driver/compression/lz4.py +21 -55
- clickhouse_driver/compression/lz4hc.py +9 -9
- clickhouse_driver/compression/zstd.py +20 -51
- clickhouse_driver/connection.py +784 -632
- clickhouse_driver/context.py +36 -36
- clickhouse_driver/dbapi/__init__.py +62 -62
- clickhouse_driver/dbapi/connection.py +99 -96
- clickhouse_driver/dbapi/cursor.py +370 -368
- clickhouse_driver/dbapi/errors.py +40 -40
- clickhouse_driver/dbapi/extras.py +73 -0
- clickhouse_driver/defines.py +55 -42
- clickhouse_driver/errors.py +453 -446
- clickhouse_driver/log.py +48 -44
- clickhouse_driver/numpy/block.py +8 -8
- clickhouse_driver/numpy/helpers.py +25 -25
- clickhouse_driver/numpy/result.py +123 -123
- clickhouse_driver/opentelemetry.py +43 -0
- clickhouse_driver/progress.py +38 -32
- clickhouse_driver/protocol.py +114 -105
- clickhouse_driver/queryprocessingstage.py +8 -8
- clickhouse_driver/reader.py +69 -69
- clickhouse_driver/readhelpers.py +26 -26
- clickhouse_driver/result.py +144 -144
- clickhouse_driver/settings/available.py +405 -405
- clickhouse_driver/settings/types.py +50 -50
- clickhouse_driver/settings/writer.py +34 -29
- clickhouse_driver/streams/compressed.py +88 -88
- clickhouse_driver/streams/native.py +102 -90
- clickhouse_driver/util/compat.py +39 -0
- clickhouse_driver/util/escape.py +94 -55
- clickhouse_driver/util/helpers.py +57 -57
- clickhouse_driver/varint.cp39-win_amd64.pyd +0 -0
- clickhouse_driver/writer.py +67 -67
- {clickhouse_driver-0.2.1.dist-info → clickhouse_driver-0.2.8.dist-info}/LICENSE +21 -21
- clickhouse_driver-0.2.8.dist-info/METADATA +201 -0
- clickhouse_driver-0.2.8.dist-info/RECORD +89 -0
- {clickhouse_driver-0.2.1.dist-info → clickhouse_driver-0.2.8.dist-info}/WHEEL +1 -1
- clickhouse_driver-0.2.1.dist-info/METADATA +0 -24
- clickhouse_driver-0.2.1.dist-info/RECORD +0 -80
- {clickhouse_driver-0.2.1.dist-info → clickhouse_driver-0.2.8.dist-info}/top_level.txt +0 -0
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
from ..util.helpers import asbool
|
|
2
|
-
from ..varint import write_varint
|
|
3
|
-
from ..writer import write_binary_str
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class SettingType(object):
|
|
7
|
-
@classmethod
|
|
8
|
-
def write(cls, value, buf):
|
|
9
|
-
raise NotImplementedError
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class SettingUInt64(SettingType):
|
|
13
|
-
@classmethod
|
|
14
|
-
def write(cls, value, buf):
|
|
15
|
-
write_varint(int(value), buf)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class SettingBool(SettingType):
|
|
19
|
-
@classmethod
|
|
20
|
-
def write(cls, value, buf):
|
|
21
|
-
write_varint(asbool(value), buf)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class SettingString(SettingType):
|
|
25
|
-
@classmethod
|
|
26
|
-
def write(cls, value, buf):
|
|
27
|
-
write_binary_str(value, buf)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class SettingChar(SettingType):
|
|
31
|
-
@classmethod
|
|
32
|
-
def write(cls, value, buf):
|
|
33
|
-
write_binary_str(value[0], buf)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
class SettingFloat(SettingType):
|
|
37
|
-
@classmethod
|
|
38
|
-
def write(cls, value, buf):
|
|
39
|
-
"""
|
|
40
|
-
Float is written in string representation.
|
|
41
|
-
"""
|
|
42
|
-
write_binary_str(str(value), buf)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class SettingMaxThreads(SettingUInt64):
|
|
46
|
-
@classmethod
|
|
47
|
-
def write(cls, value, buf):
|
|
48
|
-
if value == 'auto':
|
|
49
|
-
value = 0
|
|
50
|
-
super(SettingMaxThreads, cls).write(value, buf)
|
|
1
|
+
from ..util.helpers import asbool
|
|
2
|
+
from ..varint import write_varint
|
|
3
|
+
from ..writer import write_binary_str
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class SettingType(object):
|
|
7
|
+
@classmethod
|
|
8
|
+
def write(cls, value, buf):
|
|
9
|
+
raise NotImplementedError
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SettingUInt64(SettingType):
|
|
13
|
+
@classmethod
|
|
14
|
+
def write(cls, value, buf):
|
|
15
|
+
write_varint(int(value), buf)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class SettingBool(SettingType):
|
|
19
|
+
@classmethod
|
|
20
|
+
def write(cls, value, buf):
|
|
21
|
+
write_varint(asbool(value), buf)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class SettingString(SettingType):
|
|
25
|
+
@classmethod
|
|
26
|
+
def write(cls, value, buf):
|
|
27
|
+
write_binary_str(value, buf)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class SettingChar(SettingType):
|
|
31
|
+
@classmethod
|
|
32
|
+
def write(cls, value, buf):
|
|
33
|
+
write_binary_str(value[0], buf)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class SettingFloat(SettingType):
|
|
37
|
+
@classmethod
|
|
38
|
+
def write(cls, value, buf):
|
|
39
|
+
"""
|
|
40
|
+
Float is written in string representation.
|
|
41
|
+
"""
|
|
42
|
+
write_binary_str(str(value), buf)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class SettingMaxThreads(SettingUInt64):
|
|
46
|
+
@classmethod
|
|
47
|
+
def write(cls, value, buf):
|
|
48
|
+
if value == 'auto':
|
|
49
|
+
value = 0
|
|
50
|
+
super(SettingMaxThreads, cls).write(value, buf)
|
|
@@ -1,29 +1,34 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
|
|
3
|
-
from ..writer import write_binary_str, write_binary_uint8
|
|
4
|
-
from .available import settings as available_settings
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
logger = logging.getLogger(__name__)
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
setting_writer.
|
|
28
|
-
|
|
29
|
-
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from ..writer import write_binary_str, write_binary_uint8
|
|
4
|
+
from .available import settings as available_settings
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class SettingsFlags:
|
|
11
|
+
IMPORTANT = 0x1
|
|
12
|
+
CUSTOM = 0x2
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def write_settings(settings, buf, settings_as_strings, flags):
|
|
16
|
+
for setting, value in (settings or {}).items():
|
|
17
|
+
# If the server support settings as string we do not need to know
|
|
18
|
+
# anything about them, so we can write any setting.
|
|
19
|
+
if settings_as_strings:
|
|
20
|
+
write_binary_str(setting, buf)
|
|
21
|
+
write_binary_uint8(flags, buf)
|
|
22
|
+
write_binary_str(str(value), buf)
|
|
23
|
+
|
|
24
|
+
else:
|
|
25
|
+
# If the server requires string in binary,
|
|
26
|
+
# then they cannot be written without type.
|
|
27
|
+
setting_writer = available_settings.get(setting)
|
|
28
|
+
if not setting_writer:
|
|
29
|
+
logger.warning('Unknown setting %s. Skipping', setting)
|
|
30
|
+
continue
|
|
31
|
+
write_binary_str(setting, buf)
|
|
32
|
+
setting_writer.write(value, buf)
|
|
33
|
+
|
|
34
|
+
write_binary_str('', buf) # end of settings
|
|
@@ -1,88 +1,88 @@
|
|
|
1
|
-
from io import BytesIO
|
|
2
|
-
|
|
3
|
-
try:
|
|
4
|
-
from clickhouse_cityhash.cityhash import CityHash128
|
|
5
|
-
except ImportError:
|
|
6
|
-
raise RuntimeError(
|
|
7
|
-
'Package clickhouse-cityhash is required to use compression'
|
|
8
|
-
)
|
|
9
|
-
|
|
10
|
-
from .native import BlockOutputStream, BlockInputStream
|
|
11
|
-
from ..bufferedreader import CompressedBufferedReader
|
|
12
|
-
from ..bufferedwriter import CompressedBufferedWriter
|
|
13
|
-
from ..compression import get_decompressor_cls
|
|
14
|
-
from ..defines import BUFFER_SIZE
|
|
15
|
-
from ..reader import read_binary_uint8, read_binary_uint128
|
|
16
|
-
from ..writer import write_binary_uint8, write_binary_uint128
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class CompressedBlockOutputStream(BlockOutputStream):
|
|
20
|
-
def __init__(self, compressor_cls, compress_block_size, fout, context):
|
|
21
|
-
self.compressor_cls = compressor_cls
|
|
22
|
-
self.compress_block_size = compress_block_size
|
|
23
|
-
self.raw_fout = fout
|
|
24
|
-
|
|
25
|
-
self.compressor = self.compressor_cls()
|
|
26
|
-
self.fout = CompressedBufferedWriter(self.compressor, BUFFER_SIZE)
|
|
27
|
-
super(CompressedBlockOutputStream, self).__init__(self.fout, context)
|
|
28
|
-
|
|
29
|
-
def get_compressed_hash(self, data):
|
|
30
|
-
return CityHash128(data)
|
|
31
|
-
|
|
32
|
-
def finalize(self):
|
|
33
|
-
self.fout.flush()
|
|
34
|
-
|
|
35
|
-
compressed = self.get_compressed()
|
|
36
|
-
compressed_size = len(compressed)
|
|
37
|
-
|
|
38
|
-
compressed_hash = self.get_compressed_hash(compressed)
|
|
39
|
-
write_binary_uint128(compressed_hash, self.raw_fout)
|
|
40
|
-
|
|
41
|
-
block_size = self.compress_block_size
|
|
42
|
-
|
|
43
|
-
i = 0
|
|
44
|
-
while i < compressed_size:
|
|
45
|
-
self.raw_fout.write(compressed[i:i + block_size])
|
|
46
|
-
i += block_size
|
|
47
|
-
|
|
48
|
-
self.raw_fout.flush()
|
|
49
|
-
|
|
50
|
-
def get_compressed(self):
|
|
51
|
-
compressed = BytesIO()
|
|
52
|
-
|
|
53
|
-
if self.compressor.method_byte is not None:
|
|
54
|
-
write_binary_uint8(self.compressor.method_byte, compressed)
|
|
55
|
-
extra_header_size = 1 # method
|
|
56
|
-
else:
|
|
57
|
-
extra_header_size = 0
|
|
58
|
-
|
|
59
|
-
data = self.compressor.get_compressed_data(extra_header_size)
|
|
60
|
-
compressed.write(data)
|
|
61
|
-
|
|
62
|
-
return compressed.getvalue()
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
class CompressedBlockInputStream(BlockInputStream):
|
|
66
|
-
def __init__(self, fin, context):
|
|
67
|
-
self.raw_fin = fin
|
|
68
|
-
fin = CompressedBufferedReader(self.read_block, BUFFER_SIZE)
|
|
69
|
-
super(CompressedBlockInputStream, self).__init__(fin, context)
|
|
70
|
-
|
|
71
|
-
def get_compressed_hash(self, data):
|
|
72
|
-
return CityHash128(data)
|
|
73
|
-
|
|
74
|
-
def read_block(self):
|
|
75
|
-
compressed_hash = read_binary_uint128(self.raw_fin)
|
|
76
|
-
method_byte = read_binary_uint8(self.raw_fin)
|
|
77
|
-
|
|
78
|
-
decompressor_cls = get_decompressor_cls(method_byte)
|
|
79
|
-
decompressor = decompressor_cls(self.raw_fin)
|
|
80
|
-
|
|
81
|
-
if decompressor.method_byte is not None:
|
|
82
|
-
extra_header_size = 1 # method
|
|
83
|
-
else:
|
|
84
|
-
extra_header_size = 0
|
|
85
|
-
|
|
86
|
-
return decompressor.get_decompressed_data(
|
|
87
|
-
method_byte, compressed_hash, extra_header_size
|
|
88
|
-
)
|
|
1
|
+
from io import BytesIO
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
from clickhouse_cityhash.cityhash import CityHash128
|
|
5
|
+
except ImportError:
|
|
6
|
+
raise RuntimeError(
|
|
7
|
+
'Package clickhouse-cityhash is required to use compression'
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
from .native import BlockOutputStream, BlockInputStream
|
|
11
|
+
from ..bufferedreader import CompressedBufferedReader
|
|
12
|
+
from ..bufferedwriter import CompressedBufferedWriter
|
|
13
|
+
from ..compression import get_decompressor_cls
|
|
14
|
+
from ..defines import BUFFER_SIZE
|
|
15
|
+
from ..reader import read_binary_uint8, read_binary_uint128
|
|
16
|
+
from ..writer import write_binary_uint8, write_binary_uint128
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class CompressedBlockOutputStream(BlockOutputStream):
|
|
20
|
+
def __init__(self, compressor_cls, compress_block_size, fout, context):
|
|
21
|
+
self.compressor_cls = compressor_cls
|
|
22
|
+
self.compress_block_size = compress_block_size
|
|
23
|
+
self.raw_fout = fout
|
|
24
|
+
|
|
25
|
+
self.compressor = self.compressor_cls()
|
|
26
|
+
self.fout = CompressedBufferedWriter(self.compressor, BUFFER_SIZE)
|
|
27
|
+
super(CompressedBlockOutputStream, self).__init__(self.fout, context)
|
|
28
|
+
|
|
29
|
+
def get_compressed_hash(self, data):
|
|
30
|
+
return CityHash128(data)
|
|
31
|
+
|
|
32
|
+
def finalize(self):
|
|
33
|
+
self.fout.flush()
|
|
34
|
+
|
|
35
|
+
compressed = self.get_compressed()
|
|
36
|
+
compressed_size = len(compressed)
|
|
37
|
+
|
|
38
|
+
compressed_hash = self.get_compressed_hash(compressed)
|
|
39
|
+
write_binary_uint128(compressed_hash, self.raw_fout)
|
|
40
|
+
|
|
41
|
+
block_size = self.compress_block_size
|
|
42
|
+
|
|
43
|
+
i = 0
|
|
44
|
+
while i < compressed_size:
|
|
45
|
+
self.raw_fout.write(compressed[i:i + block_size])
|
|
46
|
+
i += block_size
|
|
47
|
+
|
|
48
|
+
self.raw_fout.flush()
|
|
49
|
+
|
|
50
|
+
def get_compressed(self):
|
|
51
|
+
compressed = BytesIO()
|
|
52
|
+
|
|
53
|
+
if self.compressor.method_byte is not None:
|
|
54
|
+
write_binary_uint8(self.compressor.method_byte, compressed)
|
|
55
|
+
extra_header_size = 1 # method
|
|
56
|
+
else:
|
|
57
|
+
extra_header_size = 0
|
|
58
|
+
|
|
59
|
+
data = self.compressor.get_compressed_data(extra_header_size)
|
|
60
|
+
compressed.write(data)
|
|
61
|
+
|
|
62
|
+
return compressed.getvalue()
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class CompressedBlockInputStream(BlockInputStream):
|
|
66
|
+
def __init__(self, fin, context):
|
|
67
|
+
self.raw_fin = fin
|
|
68
|
+
fin = CompressedBufferedReader(self.read_block, BUFFER_SIZE)
|
|
69
|
+
super(CompressedBlockInputStream, self).__init__(fin, context)
|
|
70
|
+
|
|
71
|
+
def get_compressed_hash(self, data):
|
|
72
|
+
return CityHash128(data)
|
|
73
|
+
|
|
74
|
+
def read_block(self):
|
|
75
|
+
compressed_hash = read_binary_uint128(self.raw_fin)
|
|
76
|
+
method_byte = read_binary_uint8(self.raw_fin)
|
|
77
|
+
|
|
78
|
+
decompressor_cls = get_decompressor_cls(method_byte)
|
|
79
|
+
decompressor = decompressor_cls(self.raw_fin)
|
|
80
|
+
|
|
81
|
+
if decompressor.method_byte is not None:
|
|
82
|
+
extra_header_size = 1 # method
|
|
83
|
+
else:
|
|
84
|
+
extra_header_size = 0
|
|
85
|
+
|
|
86
|
+
return decompressor.get_decompressed_data(
|
|
87
|
+
method_byte, compressed_hash, extra_header_size
|
|
88
|
+
)
|
|
@@ -1,90 +1,102 @@
|
|
|
1
|
-
from ..block import ColumnOrientedBlock, BlockInfo
|
|
2
|
-
from ..columns.service import read_column, write_column
|
|
3
|
-
from ..reader import read_binary_str
|
|
4
|
-
from ..varint import write_varint, read_varint
|
|
5
|
-
from ..writer import write_binary_str
|
|
6
|
-
from .. import defines
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class BlockOutputStream(object):
|
|
10
|
-
def __init__(self, fout, context):
|
|
11
|
-
self.fout = fout
|
|
12
|
-
self.context = context
|
|
13
|
-
|
|
14
|
-
super(BlockOutputStream, self).__init__()
|
|
15
|
-
|
|
16
|
-
def write(self, block):
|
|
17
|
-
revision = self.context.server_info.
|
|
18
|
-
if revision >= defines.DBMS_MIN_REVISION_WITH_BLOCK_INFO:
|
|
19
|
-
block.info.write(self.fout)
|
|
20
|
-
|
|
21
|
-
# We write transposed data.
|
|
22
|
-
n_columns = block.num_columns
|
|
23
|
-
n_rows = block.num_rows
|
|
24
|
-
|
|
25
|
-
write_varint(n_columns, self.fout)
|
|
26
|
-
write_varint(n_rows, self.fout)
|
|
27
|
-
|
|
28
|
-
for i, (col_name, col_type) in enumerate(block.columns_with_types):
|
|
29
|
-
write_binary_str(col_name, self.fout)
|
|
30
|
-
write_binary_str(col_type, self.fout)
|
|
31
|
-
|
|
32
|
-
if n_columns:
|
|
33
|
-
try:
|
|
34
|
-
items = block.get_column_by_index(i)
|
|
35
|
-
except IndexError:
|
|
36
|
-
raise ValueError('Different rows length')
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def
|
|
49
|
-
self.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
1
|
+
from ..block import ColumnOrientedBlock, BlockInfo
|
|
2
|
+
from ..columns.service import read_column, write_column
|
|
3
|
+
from ..reader import read_binary_str, read_binary_uint8
|
|
4
|
+
from ..varint import write_varint, read_varint
|
|
5
|
+
from ..writer import write_binary_str, write_binary_uint8
|
|
6
|
+
from .. import defines
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BlockOutputStream(object):
|
|
10
|
+
def __init__(self, fout, context):
|
|
11
|
+
self.fout = fout
|
|
12
|
+
self.context = context
|
|
13
|
+
|
|
14
|
+
super(BlockOutputStream, self).__init__()
|
|
15
|
+
|
|
16
|
+
def write(self, block):
|
|
17
|
+
revision = self.context.server_info.used_revision
|
|
18
|
+
if revision >= defines.DBMS_MIN_REVISION_WITH_BLOCK_INFO:
|
|
19
|
+
block.info.write(self.fout)
|
|
20
|
+
|
|
21
|
+
# We write transposed data.
|
|
22
|
+
n_columns = block.num_columns
|
|
23
|
+
n_rows = block.num_rows
|
|
24
|
+
|
|
25
|
+
write_varint(n_columns, self.fout)
|
|
26
|
+
write_varint(n_rows, self.fout)
|
|
27
|
+
|
|
28
|
+
for i, (col_name, col_type) in enumerate(block.columns_with_types):
|
|
29
|
+
write_binary_str(col_name, self.fout)
|
|
30
|
+
write_binary_str(col_type, self.fout)
|
|
31
|
+
|
|
32
|
+
if n_columns:
|
|
33
|
+
try:
|
|
34
|
+
items = block.get_column_by_index(i)
|
|
35
|
+
except IndexError:
|
|
36
|
+
raise ValueError('Different rows length')
|
|
37
|
+
|
|
38
|
+
if revision >= \
|
|
39
|
+
defines.DBMS_MIN_REVISION_WITH_CUSTOM_SERIALIZATION:
|
|
40
|
+
# We write always sparse data without custom serialization.
|
|
41
|
+
write_binary_uint8(0, self.fout)
|
|
42
|
+
|
|
43
|
+
write_column(self.context, col_name, col_type, items,
|
|
44
|
+
self.fout, types_check=block.types_check)
|
|
45
|
+
|
|
46
|
+
self.finalize()
|
|
47
|
+
|
|
48
|
+
def finalize(self):
|
|
49
|
+
self.fout.flush()
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class BlockInputStream(object):
|
|
53
|
+
def __init__(self, fin, context):
|
|
54
|
+
self.fin = fin
|
|
55
|
+
self.context = context
|
|
56
|
+
|
|
57
|
+
super(BlockInputStream, self).__init__()
|
|
58
|
+
|
|
59
|
+
def read(self, use_numpy=None):
|
|
60
|
+
info = BlockInfo()
|
|
61
|
+
|
|
62
|
+
revision = self.context.server_info.used_revision
|
|
63
|
+
if revision >= defines.DBMS_MIN_REVISION_WITH_BLOCK_INFO:
|
|
64
|
+
info.read(self.fin)
|
|
65
|
+
|
|
66
|
+
n_columns = read_varint(self.fin)
|
|
67
|
+
n_rows = read_varint(self.fin)
|
|
68
|
+
|
|
69
|
+
data, names, types = [], [], []
|
|
70
|
+
|
|
71
|
+
for i in range(n_columns):
|
|
72
|
+
column_name = read_binary_str(self.fin)
|
|
73
|
+
column_type = read_binary_str(self.fin)
|
|
74
|
+
|
|
75
|
+
names.append(column_name)
|
|
76
|
+
types.append(column_type)
|
|
77
|
+
|
|
78
|
+
has_custom_serialization = False
|
|
79
|
+
if revision >= defines.DBMS_MIN_REVISION_WITH_CUSTOM_SERIALIZATION:
|
|
80
|
+
has_custom_serialization = bool(read_binary_uint8(self.fin))
|
|
81
|
+
|
|
82
|
+
if n_rows:
|
|
83
|
+
column = read_column(
|
|
84
|
+
self.context, column_type, n_rows,
|
|
85
|
+
self.fin, use_numpy=use_numpy,
|
|
86
|
+
has_custom_serialization=has_custom_serialization
|
|
87
|
+
)
|
|
88
|
+
data.append(column)
|
|
89
|
+
|
|
90
|
+
if self.context.client_settings['use_numpy']:
|
|
91
|
+
from ..numpy.block import NumpyColumnOrientedBlock
|
|
92
|
+
block_cls = NumpyColumnOrientedBlock
|
|
93
|
+
else:
|
|
94
|
+
block_cls = ColumnOrientedBlock
|
|
95
|
+
|
|
96
|
+
block = block_cls(
|
|
97
|
+
columns_with_types=list(zip(names, types)),
|
|
98
|
+
data=data,
|
|
99
|
+
info=info,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
return block
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
|
|
2
|
+
# Drop this when minimum supported version will be 3.7.
|
|
3
|
+
try:
|
|
4
|
+
import threading
|
|
5
|
+
except ImportError:
|
|
6
|
+
import dummy_threading as threading # noqa: F401
|
|
7
|
+
|
|
8
|
+
import json # noqa: F401
|
|
9
|
+
try:
|
|
10
|
+
import orjson as json # noqa: F811
|
|
11
|
+
except ImportError:
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
try:
|
|
15
|
+
import ujson as json # noqa: F811,F401
|
|
16
|
+
except ImportError:
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
try:
|
|
21
|
+
# since tzlocal 4.0+
|
|
22
|
+
# this will avoid warning for get_localzone().key
|
|
23
|
+
from tzlocal import get_localzone_name
|
|
24
|
+
|
|
25
|
+
def get_localzone_name_compat():
|
|
26
|
+
try:
|
|
27
|
+
return get_localzone_name()
|
|
28
|
+
except Exception:
|
|
29
|
+
return None
|
|
30
|
+
except ImportError:
|
|
31
|
+
from tzlocal import get_localzone
|
|
32
|
+
|
|
33
|
+
def get_localzone_name_compat():
|
|
34
|
+
try:
|
|
35
|
+
return get_localzone().key
|
|
36
|
+
except AttributeError:
|
|
37
|
+
return get_localzone().zone
|
|
38
|
+
except Exception:
|
|
39
|
+
return None
|