vastdb 1.4.0__py3-none-any.whl → 2.0.0__py3-none-any.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.
- vastdb/_ibis_support.py +28 -0
- vastdb/_internal.py +167 -180
- vastdb/_table_interface.py +136 -0
- vastdb/bench/perf_bench/orchestrate/results_helpers.py +1 -1
- vastdb/bucket.py +1 -1
- vastdb/conftest.py +42 -19
- vastdb/schema.py +15 -3
- vastdb/session.py +3 -1
- vastdb/table.py +595 -340
- vastdb/table_metadata.py +221 -0
- vastdb/tests/test_duckdb.py +30 -30
- vastdb/tests/test_fixed_list.py +56 -6
- vastdb/tests/test_imports.py +2 -1
- vastdb/tests/test_nested.py +0 -5
- vastdb/tests/test_table_in_tx.py +249 -0
- vastdb/tests/test_tables.py +57 -11
- vastdb/tests/util.py +98 -1
- vastdb/transaction.py +27 -0
- {vastdb-1.4.0.dist-info → vastdb-2.0.0.dist-info}/METADATA +21 -6
- {vastdb-1.4.0.dist-info → vastdb-2.0.0.dist-info}/RECORD +23 -19
- {vastdb-1.4.0.dist-info → vastdb-2.0.0.dist-info}/WHEEL +1 -1
- {vastdb-1.4.0.dist-info → vastdb-2.0.0.dist-info/licenses}/LICENSE +0 -0
- {vastdb-1.4.0.dist-info → vastdb-2.0.0.dist-info}/top_level.txt +0 -0
vastdb/bucket.py
CHANGED
|
@@ -36,7 +36,7 @@ class Bucket:
|
|
|
36
36
|
"""Get a specific schema (a container of tables) under this bucket."""
|
|
37
37
|
return self._root_schema.schema(name=name, fail_if_missing=fail_if_missing)
|
|
38
38
|
|
|
39
|
-
def schemas(self, batch_size=None):
|
|
39
|
+
def schemas(self, batch_size: Optional[int] = None) -> Iterable["Schema"]:
|
|
40
40
|
"""List bucket's schemas."""
|
|
41
41
|
return self._root_schema.schemas(batch_size=batch_size)
|
|
42
42
|
|
vastdb/conftest.py
CHANGED
|
@@ -1,20 +1,42 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import sqlite3
|
|
3
3
|
from pathlib import Path
|
|
4
|
+
from typing import Iterable
|
|
4
5
|
|
|
5
6
|
import boto3
|
|
6
7
|
import pytest
|
|
7
8
|
|
|
8
9
|
import vastdb
|
|
9
10
|
import vastdb.errors
|
|
11
|
+
from vastdb.schema import Schema
|
|
12
|
+
from vastdb.session import Session
|
|
13
|
+
|
|
14
|
+
AWS_ACCESS_KEY_ID = "AWS_ACCESS_KEY_ID"
|
|
15
|
+
AWS_SECRET_ACCESS_KEY = "AWS_SECRET_ACCESS_KEY"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def get_aws_cred_from_system(cred_name):
|
|
19
|
+
orion_dir = Path(os.path.expanduser(os.environ.get("ORION_DIR", "~/orion")))
|
|
20
|
+
orion_file_path = orion_dir / 'data' / cred_name
|
|
21
|
+
|
|
22
|
+
env_value = os.environ.get(cred_name)
|
|
23
|
+
|
|
24
|
+
if env_value is not None:
|
|
25
|
+
return env_value
|
|
26
|
+
|
|
27
|
+
if not orion_file_path.exists():
|
|
28
|
+
return None
|
|
29
|
+
|
|
30
|
+
with open(orion_file_path, "r") as f:
|
|
31
|
+
return f.read().strip()
|
|
10
32
|
|
|
11
33
|
|
|
12
34
|
def pytest_addoption(parser):
|
|
13
35
|
parser.addoption("--tabular-bucket-name", help="Name of the S3 bucket with Tabular enabled", default="vastdb")
|
|
14
36
|
parser.addoption("--tabular-access-key", help="Access key with Tabular permissions (AWS_ACCESS_KEY_ID)",
|
|
15
|
-
default=
|
|
37
|
+
default=get_aws_cred_from_system(AWS_ACCESS_KEY_ID))
|
|
16
38
|
parser.addoption("--tabular-secret-key", help="Secret key with Tabular permissions (AWS_SECRET_ACCESS_KEY)",
|
|
17
|
-
default=
|
|
39
|
+
default=get_aws_cred_from_system(AWS_SECRET_ACCESS_KEY))
|
|
18
40
|
parser.addoption("--tabular-endpoint-url", help="Tabular server endpoint", default=[], action="append")
|
|
19
41
|
parser.addoption("--data-path", help="Data files location", default=None)
|
|
20
42
|
parser.addoption("--crater-path", help="Save benchmark results in a dedicated location", default=None)
|
|
@@ -24,7 +46,7 @@ def pytest_addoption(parser):
|
|
|
24
46
|
|
|
25
47
|
|
|
26
48
|
@pytest.fixture(scope="session")
|
|
27
|
-
def session_kwargs(request, tabular_endpoint_urls):
|
|
49
|
+
def session_kwargs(request: pytest.FixtureRequest, tabular_endpoint_urls):
|
|
28
50
|
return dict(
|
|
29
51
|
access=request.config.getoption("--tabular-access-key"),
|
|
30
52
|
secret=request.config.getoption("--tabular-secret-key"),
|
|
@@ -38,30 +60,30 @@ def session(session_kwargs):
|
|
|
38
60
|
|
|
39
61
|
|
|
40
62
|
@pytest.fixture(scope="session")
|
|
41
|
-
def num_workers(request):
|
|
63
|
+
def num_workers(request: pytest.FixtureRequest):
|
|
42
64
|
return int(request.config.getoption("--num-workers"))
|
|
43
65
|
|
|
44
66
|
|
|
45
67
|
@pytest.fixture(scope="session")
|
|
46
|
-
def test_bucket_name(request):
|
|
68
|
+
def test_bucket_name(request: pytest.FixtureRequest):
|
|
47
69
|
return request.config.getoption("--tabular-bucket-name")
|
|
48
70
|
|
|
49
71
|
|
|
50
72
|
@pytest.fixture(scope="session")
|
|
51
|
-
def tabular_endpoint_urls(request):
|
|
73
|
+
def tabular_endpoint_urls(request: pytest.FixtureRequest):
|
|
52
74
|
return request.config.getoption("--tabular-endpoint-url") or ["http://localhost:9090"]
|
|
53
75
|
|
|
54
76
|
|
|
55
|
-
def iter_schemas(
|
|
56
|
-
"""
|
|
57
|
-
children =
|
|
58
|
-
for
|
|
59
|
-
yield from iter_schemas(
|
|
60
|
-
yield
|
|
77
|
+
def iter_schemas(schema: Schema) -> Iterable[Schema]:
|
|
78
|
+
"""Recursively scan all schemas."""
|
|
79
|
+
children = schema.schemas()
|
|
80
|
+
for child in children:
|
|
81
|
+
yield from iter_schemas(child)
|
|
82
|
+
yield schema
|
|
61
83
|
|
|
62
84
|
|
|
63
85
|
@pytest.fixture(scope="function")
|
|
64
|
-
def clean_bucket_name(request, test_bucket_name, session):
|
|
86
|
+
def clean_bucket_name(request: pytest.FixtureRequest, test_bucket_name: str, session: Session) -> str:
|
|
65
87
|
with session.transaction() as tx:
|
|
66
88
|
b = tx.bucket(test_bucket_name)
|
|
67
89
|
for top_schema in b.schemas():
|
|
@@ -69,7 +91,8 @@ def clean_bucket_name(request, test_bucket_name, session):
|
|
|
69
91
|
for t_name in s.tablenames():
|
|
70
92
|
try:
|
|
71
93
|
t = s.table(t_name)
|
|
72
|
-
t
|
|
94
|
+
if t is not None:
|
|
95
|
+
t.drop()
|
|
73
96
|
except vastdb.errors.NotSupportedSchema:
|
|
74
97
|
# Use internal API to drop the table in case unsupported schema prevents creating a table
|
|
75
98
|
# object.
|
|
@@ -79,7 +102,7 @@ def clean_bucket_name(request, test_bucket_name, session):
|
|
|
79
102
|
|
|
80
103
|
|
|
81
104
|
@pytest.fixture(scope="session")
|
|
82
|
-
def s3(request, tabular_endpoint_urls):
|
|
105
|
+
def s3(request: pytest.FixtureRequest, tabular_endpoint_urls):
|
|
83
106
|
return boto3.client(
|
|
84
107
|
's3',
|
|
85
108
|
aws_access_key_id=request.config.getoption("--tabular-access-key"),
|
|
@@ -88,22 +111,22 @@ def s3(request, tabular_endpoint_urls):
|
|
|
88
111
|
|
|
89
112
|
|
|
90
113
|
@pytest.fixture(scope="function")
|
|
91
|
-
def parquets_path(request):
|
|
114
|
+
def parquets_path(request: pytest.FixtureRequest):
|
|
92
115
|
return Path(request.config.getoption("--data-path"))
|
|
93
116
|
|
|
94
117
|
|
|
95
118
|
@pytest.fixture(scope="function")
|
|
96
|
-
def crater_path(request):
|
|
119
|
+
def crater_path(request: pytest.FixtureRequest):
|
|
97
120
|
return request.config.getoption("--crater-path")
|
|
98
121
|
|
|
99
122
|
|
|
100
123
|
@pytest.fixture(scope="function")
|
|
101
|
-
def schema_name(request):
|
|
124
|
+
def schema_name(request: pytest.FixtureRequest):
|
|
102
125
|
return request.config.getoption("--schema-name")
|
|
103
126
|
|
|
104
127
|
|
|
105
128
|
@pytest.fixture(scope="function")
|
|
106
|
-
def table_name(request):
|
|
129
|
+
def table_name(request: pytest.FixtureRequest):
|
|
107
130
|
return request.config.getoption("--table-name")
|
|
108
131
|
|
|
109
132
|
|
vastdb/schema.py
CHANGED
|
@@ -10,7 +10,10 @@ from typing import TYPE_CHECKING, Iterable, List, Optional
|
|
|
10
10
|
|
|
11
11
|
import pyarrow as pa
|
|
12
12
|
|
|
13
|
+
from vastdb.table_metadata import TableMetadata, TableRef, TableType
|
|
14
|
+
|
|
13
15
|
from . import bucket, errors, schema, table
|
|
16
|
+
from ._ibis_support import validate_ibis_support_schema
|
|
14
17
|
|
|
15
18
|
if TYPE_CHECKING:
|
|
16
19
|
from .table import Table
|
|
@@ -91,7 +94,7 @@ class Schema:
|
|
|
91
94
|
if use_external_row_ids_allocation:
|
|
92
95
|
self.tx._rpc.features.check_external_row_ids_allocation()
|
|
93
96
|
|
|
94
|
-
|
|
97
|
+
validate_ibis_support_schema(columns)
|
|
95
98
|
self.tx._rpc.api.create_table(self.bucket.name, self.name, table_name, columns, txid=self.tx.txid,
|
|
96
99
|
use_external_row_ids_allocation=use_external_row_ids_allocation,
|
|
97
100
|
sorting_key=sorting_key)
|
|
@@ -117,7 +120,7 @@ class Schema:
|
|
|
117
120
|
while True:
|
|
118
121
|
_bucket_name, _schema_name, curr_tables, next_key, is_truncated, _ = \
|
|
119
122
|
self.tx._rpc.api.list_tables(
|
|
120
|
-
bucket=self.bucket.name, schema=self.name, next_key=next_key, max_keys=page_size, txid=self.tx.
|
|
123
|
+
bucket=self.bucket.name, schema=self.name, next_key=next_key, max_keys=page_size, txid=self.tx.active_txid,
|
|
121
124
|
exact_match=exact_match, name_prefix=name_prefix, include_list_stats=exact_match)
|
|
122
125
|
if not curr_tables:
|
|
123
126
|
break
|
|
@@ -152,4 +155,13 @@ class Schema:
|
|
|
152
155
|
|
|
153
156
|
|
|
154
157
|
def _parse_table_info(table_info, schema: "schema.Schema"):
|
|
155
|
-
|
|
158
|
+
ref = TableRef(bucket=schema.bucket.name,
|
|
159
|
+
schema=schema.name,
|
|
160
|
+
table=table_info.name)
|
|
161
|
+
|
|
162
|
+
table_type = TableType.Elysium if table_info.sorting_key_enabled else TableType.Regular
|
|
163
|
+
table_metadata = TableMetadata(ref, table_type=table_type)
|
|
164
|
+
|
|
165
|
+
return table.Table(handle=int(table_info.handle),
|
|
166
|
+
metadata=table_metadata,
|
|
167
|
+
tx=schema.tx)
|
vastdb/session.py
CHANGED
|
@@ -10,6 +10,8 @@ For more details see:
|
|
|
10
10
|
import os
|
|
11
11
|
from typing import TYPE_CHECKING, Optional
|
|
12
12
|
|
|
13
|
+
from vastdb.transaction import Transaction
|
|
14
|
+
|
|
13
15
|
if TYPE_CHECKING:
|
|
14
16
|
from .config import BackoffConfig
|
|
15
17
|
|
|
@@ -45,7 +47,7 @@ class Session:
|
|
|
45
47
|
"""Don't show the secret key."""
|
|
46
48
|
return f'{self.__class__.__name__}(endpoint={self.api.url}, access={self.api.access_key})'
|
|
47
49
|
|
|
48
|
-
def transaction(self):
|
|
50
|
+
def transaction(self) -> Transaction:
|
|
49
51
|
"""Create a non-initialized transaction object.
|
|
50
52
|
|
|
51
53
|
It should be used as a context manager:
|