vastdb 0.1.4__tar.gz → 0.1.6__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.
- {vastdb-0.1.4 → vastdb-0.1.6}/CHANGELOG.md +25 -0
- {vastdb-0.1.4/vastdb.egg-info → vastdb-0.1.6}/PKG-INFO +1 -1
- {vastdb-0.1.4 → vastdb-0.1.6}/README.md +8 -4
- {vastdb-0.1.4 → vastdb-0.1.6}/setup.py +3 -2
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/bench/test_perf.py +1 -2
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/bucket.py +12 -37
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/conftest.py +13 -4
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/errors.py +5 -1
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/internal_commands.py +26 -90
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/schema.py +45 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/session.py +26 -10
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/table.py +48 -8
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/tests/test_imports.py +3 -3
- vastdb-0.1.6/vastdb/tests/test_nested.py +102 -0
- vastdb-0.1.6/vastdb/tests/test_projections.py +121 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/tests/test_schemas.py +49 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/tests/test_tables.py +123 -95
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/transaction.py +24 -15
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/util.py +1 -0
- {vastdb-0.1.4 → vastdb-0.1.6/vastdb.egg-info}/PKG-INFO +1 -1
- vastdb-0.1.4/vastdb/tests/test_nested.py +0 -28
- vastdb-0.1.4/vastdb/tests/test_projections.py +0 -43
- {vastdb-0.1.4 → vastdb-0.1.6}/LICENSE +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/MANIFEST.in +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/requirements.txt +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/setup.cfg +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/__init__.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/__init__.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/__init__.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/__init__.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/__init__.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Aggregate.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ArraySlice.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ArraySubscript.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/BinaryLiteral.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/BooleanLiteral.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Bound.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Call.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/CaseFragment.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Cast.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ConcreteBoundImpl.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ConditionalCase.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/CurrentRow.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/DateLiteral.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/DecimalLiteral.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Deref.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/DurationLiteral.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Expression.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ExpressionImpl.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/FieldIndex.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/FieldRef.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Filter.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/FixedSizeBinaryLiteral.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Float16Literal.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Float32Literal.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Float64Literal.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Following.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Frame.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Grouping.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int16Literal.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int32Literal.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int64Literal.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int8Literal.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteral.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteralDaysMilliseconds.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteralImpl.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteralMonths.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Join.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/JoinKind.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/KeyValue.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Limit.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ListLiteral.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Literal.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/LiteralColumn.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/LiteralImpl.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/LiteralRelation.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/MapKey.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/MapLiteral.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/OrderBy.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Ordering.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Plan.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Preceding.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Project.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/RelId.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Relation.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/RelationImpl.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SetOpKind.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SetOperation.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SimpleCase.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SortKey.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Source.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/StringLiteral.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/StructField.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/StructLiteral.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/TimeLiteral.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/TimestampLiteral.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt16Literal.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt32Literal.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt64Literal.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt8Literal.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Unbounded.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/WindowCall.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/__init__.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Binary.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Block.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/BodyCompression.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/BodyCompressionMethod.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Bool.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Buffer.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/CompressionType.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Date.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/DateUnit.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Decimal.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/DictionaryBatch.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/DictionaryEncoding.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/DictionaryKind.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Duration.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Endianness.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Feature.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Field.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/FieldNode.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/FixedSizeBinary.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/FixedSizeList.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/FloatingPoint.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Footer.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Int.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Interval.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/IntervalUnit.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/KeyValue.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/LargeBinary.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/LargeList.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/LargeUtf8.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/List.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Map.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Message.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/MessageHeader.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/MetadataVersion.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Null.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Precision.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/RecordBatch.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Schema.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseMatrixCompressedAxis.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseMatrixIndexCSX.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensor.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensorIndex.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensorIndexCOO.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensorIndexCSF.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Struct_.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Tensor.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/TensorDim.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Time.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/TimeUnit.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Timestamp.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Type.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Union.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/UnionMode.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Utf8.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/__init__.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/AlterColumnRequest.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/AlterProjectionTableRequest.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/AlterSchemaRequest.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/AlterTableRequest.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/Column.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/ColumnType.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/CreateProjectionRequest.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/CreateSchemaRequest.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/GetProjectionTableStatsResponse.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/GetTableStatsResponse.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/ImportDataRequest.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/ListProjectionsResponse.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/ListSchemasResponse.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/ListTablesResponse.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/ObjectDetails.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/S3File.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/VipRange.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/__init__.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/__init__.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/bench/__init__.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/tests/__init__.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/tests/test_duckdb.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/tests/test_sanity.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/tests/test_util.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/tests/util.py +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb.egg-info/SOURCES.txt +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb.egg-info/dependency_links.txt +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb.egg-info/requires.txt +0 -0
- {vastdb-0.1.4 → vastdb-0.1.6}/vastdb.egg-info/top_level.txt +0 -0
|
@@ -4,6 +4,31 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
6
6
|
|
|
7
|
+
## [0.1.6] (2024-05-23)
|
|
8
|
+
[0.1.6]: https://github.com/vast-data/vastdb_sdk/compare/v0.1.5...v0.1.6
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Allow listing and querying Catalog snapshots
|
|
12
|
+
- Support nested schemas
|
|
13
|
+
- Use automatic split estimation
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- Allow using specific semi-sorted projection (needs VAST 5.1+ release)
|
|
17
|
+
- Add a client-side check for too large requests
|
|
18
|
+
|
|
19
|
+
## [0.1.5] (2024-05-16)
|
|
20
|
+
[0.1.5]: https://github.com/vast-data/vastdb_sdk/compare/v0.1.4...v0.1.5
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
- Allow passing `ssl_verify` via `Session` c-tor
|
|
24
|
+
- Retry `requests.exceptions.ConnectionError`
|
|
25
|
+
- Document `QueryConfig` properties
|
|
26
|
+
- Support "deferred" `ibis` predicates using [Underscore (`_`) API](https://github.com/ibis-project/ibis/pull/3804)
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
- Fix predicate pushdown when nested columns are present
|
|
30
|
+
- Attach original traceback to `MissingBucket` exception
|
|
31
|
+
|
|
7
32
|
## [0.1.4] (2024-05-13)
|
|
8
33
|
[0.1.4]: https://github.com/vast-data/vastdb_sdk/compare/v0.1.3...v0.1.4
|
|
9
34
|
|
|
@@ -74,16 +74,18 @@ with session.transaction() as tx:
|
|
|
74
74
|
Our SDK supports predicate and projection pushdown:
|
|
75
75
|
|
|
76
76
|
```python
|
|
77
|
+
from ibis import _
|
|
78
|
+
|
|
77
79
|
# SELECT c1 FROM t WHERE (c2 > 2) AND (c3 IS NULL)
|
|
78
80
|
table.select(columns=['c1'],
|
|
79
|
-
predicate=(
|
|
81
|
+
predicate=(_.c2 > 2) & _.c3.isnull())
|
|
80
82
|
|
|
81
83
|
# SELECT c2, c3 FROM t WHERE (c2 BETWEEN 0 AND 1) OR (c2 > 10)
|
|
82
84
|
table.select(columns=['c2', 'c3'],
|
|
83
|
-
predicate=
|
|
85
|
+
predicate=(_.c2.between(0, 1) | (table['c2'] > 10))
|
|
84
86
|
|
|
85
87
|
# SELECT * FROM t WHERE c3 LIKE '%substring%'
|
|
86
|
-
table.select(predicate=
|
|
88
|
+
table.select(predicate=_.c3.contains('substring'))
|
|
87
89
|
```
|
|
88
90
|
|
|
89
91
|
See [here for more details](docs/predicate.md).
|
|
@@ -132,10 +134,12 @@ with contextlib.closing(pa.parquet.ParquetWriter('/path/to/file.parquet', batche
|
|
|
132
134
|
We can use [DuckDB](https://duckdb.org/docs/guides/python/sql_on_arrow.html) to post-process the resulting stream of [PyArrow record batches](https://arrow.apache.org/docs/python/data.html#record-batches):
|
|
133
135
|
|
|
134
136
|
```python
|
|
137
|
+
from ibis import _
|
|
138
|
+
|
|
135
139
|
import duckdb
|
|
136
140
|
conn = duckdb.connect()
|
|
137
141
|
|
|
138
|
-
batches = table.select(columns=['c1'], predicate=(
|
|
142
|
+
batches = table.select(columns=['c1'], predicate=(_.c2 > 2))
|
|
139
143
|
print(conn.execute("SELECT sum(c1) FROM batches").arrow())
|
|
140
144
|
```
|
|
141
145
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import os
|
|
2
|
+
from pathlib import Path
|
|
2
3
|
|
|
3
4
|
from setuptools import find_packages, setup
|
|
4
5
|
|
|
@@ -28,13 +29,13 @@ setup(
|
|
|
28
29
|
name='vastdb',
|
|
29
30
|
python_requires='>=3.9.0',
|
|
30
31
|
description='VAST Data SDK',
|
|
31
|
-
version='0.1.
|
|
32
|
+
version='0.1.6' + suffix,
|
|
32
33
|
url='https://github.com/vast-data/vastdb_sdk',
|
|
33
34
|
author='VAST DATA',
|
|
34
35
|
author_email='hello@vastdata.com',
|
|
35
36
|
license='Copyright (C) VAST Data Ltd.',
|
|
36
37
|
packages=find_packages(),
|
|
37
|
-
install_requires=
|
|
38
|
+
install_requires=Path('requirements.txt').read_text().strip().split(),
|
|
38
39
|
long_description=long_description,
|
|
39
40
|
long_description_content_type='text/markdown',
|
|
40
41
|
classifiers=[
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import time
|
|
3
3
|
|
|
4
|
-
import pyarrow as pa
|
|
5
4
|
import pytest
|
|
6
5
|
|
|
7
6
|
from vastdb import util
|
|
@@ -20,7 +19,7 @@ def test_bench(session, clean_bucket_name, parquets_path, crater_path):
|
|
|
20
19
|
t = util.create_table_from_files(s, 't1', files, config=ImportConfig(import_concurrency=8))
|
|
21
20
|
config = QueryConfig(num_splits=8, num_sub_splits=4)
|
|
22
21
|
s = time.time()
|
|
23
|
-
pa_table =
|
|
22
|
+
pa_table = t.select(columns=['sid'], predicate=t['sid'] == 10033007, config=config).read_all()
|
|
24
23
|
e = time.time()
|
|
25
24
|
log.info("'SELECT sid from TABLE WHERE sid = 10033007' returned in %s seconds.", e - s)
|
|
26
25
|
if crater_path:
|
|
@@ -5,7 +5,7 @@ It is possible to list and access VAST snapshots generated over a bucket.
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import logging
|
|
8
|
-
from dataclasses import dataclass
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
9
|
from typing import TYPE_CHECKING, List, Optional
|
|
10
10
|
|
|
11
11
|
from . import errors, schema, transaction
|
|
@@ -22,48 +22,23 @@ class Bucket:
|
|
|
22
22
|
|
|
23
23
|
name: str
|
|
24
24
|
tx: "transaction.Transaction"
|
|
25
|
+
_root_schema: "Schema" = field(init=False, compare=False, repr=False)
|
|
25
26
|
|
|
26
|
-
def
|
|
27
|
+
def __post_init__(self):
|
|
28
|
+
"""Root schema is empty."""
|
|
29
|
+
self._root_schema = schema.Schema(name="", bucket=self)
|
|
30
|
+
|
|
31
|
+
def create_schema(self, name: str, fail_if_exists=True) -> "Schema":
|
|
27
32
|
"""Create a new schema (a container of tables) under this bucket."""
|
|
28
|
-
|
|
29
|
-
if fail_if_exists:
|
|
30
|
-
raise errors.SchemaExists(self.name, path)
|
|
31
|
-
else:
|
|
32
|
-
return current
|
|
33
|
-
self.tx._rpc.api.create_schema(self.name, path, txid=self.tx.txid)
|
|
34
|
-
log.info("Created schema: %s", path)
|
|
35
|
-
return self.schema(path) # type: ignore[return-value]
|
|
33
|
+
return self._root_schema.create_schema(name=name, fail_if_exists=fail_if_exists)
|
|
36
34
|
|
|
37
|
-
def schema(self,
|
|
35
|
+
def schema(self, name: str, fail_if_missing=True) -> Optional["Schema"]:
|
|
38
36
|
"""Get a specific schema (a container of tables) under this bucket."""
|
|
39
|
-
|
|
40
|
-
log.debug("schema: %s", s)
|
|
41
|
-
if not s:
|
|
42
|
-
if fail_if_missing:
|
|
43
|
-
raise errors.MissingSchema(self.name, path)
|
|
44
|
-
else:
|
|
45
|
-
return None
|
|
46
|
-
assert len(s) == 1, f"Expected to receive only a single schema, but got: {len(s)}. ({s})"
|
|
47
|
-
log.debug("Found schema: %s", s[0].name)
|
|
48
|
-
return s[0]
|
|
37
|
+
return self._root_schema.schema(name=name, fail_if_missing=fail_if_missing)
|
|
49
38
|
|
|
50
|
-
def schemas(self,
|
|
39
|
+
def schemas(self, batch_size=None):
|
|
51
40
|
"""List bucket's schemas."""
|
|
52
|
-
schemas
|
|
53
|
-
next_key = 0
|
|
54
|
-
exact_match = bool(name)
|
|
55
|
-
log.debug("list schemas param: schema=%s, exact_match=%s", name, exact_match)
|
|
56
|
-
while True:
|
|
57
|
-
_bucket_name, curr_schemas, next_key, is_truncated, _ = \
|
|
58
|
-
self.tx._rpc.api.list_schemas(bucket=self.name, next_key=next_key, txid=self.tx.txid,
|
|
59
|
-
name_prefix=name, exact_match=exact_match)
|
|
60
|
-
if not curr_schemas:
|
|
61
|
-
break
|
|
62
|
-
schemas.extend(curr_schemas)
|
|
63
|
-
if not is_truncated:
|
|
64
|
-
break
|
|
65
|
-
|
|
66
|
-
return [schema.Schema(name=name, bucket=self) for name, *_ in schemas]
|
|
41
|
+
return self._root_schema.schemas(batch_size=batch_size)
|
|
67
42
|
|
|
68
43
|
def snapshot(self, name, fail_if_missing=True) -> Optional["Bucket"]:
|
|
69
44
|
"""Get snapshot by name (if exists)."""
|
|
@@ -30,14 +30,23 @@ def test_bucket_name(request):
|
|
|
30
30
|
return request.config.getoption("--tabular-bucket-name")
|
|
31
31
|
|
|
32
32
|
|
|
33
|
+
def iter_schemas(s):
|
|
34
|
+
"""Recusively scan all schemas."""
|
|
35
|
+
children = s.schemas()
|
|
36
|
+
for c in children:
|
|
37
|
+
yield from iter_schemas(c)
|
|
38
|
+
yield s
|
|
39
|
+
|
|
40
|
+
|
|
33
41
|
@pytest.fixture(scope="function")
|
|
34
42
|
def clean_bucket_name(request, test_bucket_name, session):
|
|
35
43
|
with session.transaction() as tx:
|
|
36
44
|
b = tx.bucket(test_bucket_name)
|
|
37
|
-
for
|
|
38
|
-
for
|
|
39
|
-
t.
|
|
40
|
-
|
|
45
|
+
for top_schema in b.schemas():
|
|
46
|
+
for s in iter_schemas(top_schema):
|
|
47
|
+
for t in s.tables():
|
|
48
|
+
t.drop()
|
|
49
|
+
s.drop()
|
|
41
50
|
return test_bucket_name
|
|
42
51
|
|
|
43
52
|
|
|
@@ -6,7 +6,6 @@ import struct
|
|
|
6
6
|
import urllib.parse
|
|
7
7
|
from collections import defaultdict, namedtuple
|
|
8
8
|
from enum import Enum
|
|
9
|
-
from ipaddress import IPv4Address, IPv6Address
|
|
10
9
|
from typing import Any, Dict, Iterator, List, Optional, Union
|
|
11
10
|
|
|
12
11
|
import flatbuffers
|
|
@@ -130,46 +129,13 @@ def get_unit_to_flatbuff_time_unit(type):
|
|
|
130
129
|
class Predicate:
|
|
131
130
|
def __init__(self, schema: 'pa.Schema', expr: ibis.expr.types.BooleanColumn):
|
|
132
131
|
self.schema = schema
|
|
132
|
+
index = itertools.count() # used to generate leaf column positions for VAST QueryData RPC
|
|
133
|
+
# Arrow schema contains the top-level columns, where each column may include multiple subfields
|
|
134
|
+
# We use DFS is used to enumerate all the sub-columns, using `index` as an ID allocator
|
|
135
|
+
nodes = [FieldNode(field, index) for field in schema]
|
|
136
|
+
self.nodes_map = {node.field.name: node for node in nodes}
|
|
133
137
|
self.expr = expr
|
|
134
138
|
|
|
135
|
-
def get_field_indexes(self, field: 'pa.Field', field_name_per_index: list) -> None:
|
|
136
|
-
field_name_per_index.append(field.name)
|
|
137
|
-
|
|
138
|
-
if isinstance(field.type, pa.StructType):
|
|
139
|
-
flat_fields = field.flatten()
|
|
140
|
-
elif isinstance(field.type, pa.MapType):
|
|
141
|
-
flat_fields = [pa.field(f'{field.name}.entries', pa.struct([field.type.key_field, field.type.item_field]))]
|
|
142
|
-
elif isinstance(field.type, pa.ListType):
|
|
143
|
-
flat_fields = [pa.field(f'{field.name}.{field.type.value_field.name}', field.type.value_field.type)]
|
|
144
|
-
else:
|
|
145
|
-
return
|
|
146
|
-
|
|
147
|
-
for flat_field in flat_fields:
|
|
148
|
-
self.get_field_indexes(flat_field, field_name_per_index)
|
|
149
|
-
|
|
150
|
-
@property
|
|
151
|
-
def field_name_per_index(self):
|
|
152
|
-
if self._field_name_per_index is None:
|
|
153
|
-
_field_name_per_index = []
|
|
154
|
-
for field in self.schema:
|
|
155
|
-
self.get_field_indexes(field, _field_name_per_index)
|
|
156
|
-
self._field_name_per_index = {field: index for index, field in enumerate(_field_name_per_index)}
|
|
157
|
-
return self._field_name_per_index
|
|
158
|
-
|
|
159
|
-
def get_projections(self, builder: 'flatbuffers.builder.Builder', field_names: Optional[List[str]] = None):
|
|
160
|
-
if field_names is None:
|
|
161
|
-
field_names = self.field_name_per_index.keys()
|
|
162
|
-
projection_fields = []
|
|
163
|
-
for field_name in field_names:
|
|
164
|
-
fb_field_index.Start(builder)
|
|
165
|
-
fb_field_index.AddPosition(builder, self.field_name_per_index[field_name])
|
|
166
|
-
offset = fb_field_index.End(builder)
|
|
167
|
-
projection_fields.append(offset)
|
|
168
|
-
fb_source.StartProjectionVector(builder, len(projection_fields))
|
|
169
|
-
for offset in reversed(projection_fields):
|
|
170
|
-
builder.PrependUOffsetTRelative(offset)
|
|
171
|
-
return builder.EndVector()
|
|
172
|
-
|
|
173
139
|
def serialize(self, builder: 'flatbuffers.builder.Builder'):
|
|
174
140
|
from ibis.expr.operations.generic import (
|
|
175
141
|
IsNull,
|
|
@@ -204,8 +170,6 @@ class Predicate:
|
|
|
204
170
|
Between: self.build_between,
|
|
205
171
|
}
|
|
206
172
|
|
|
207
|
-
positions_map = dict((f.name, index) for index, f in enumerate(self.schema)) # TODO: BFS
|
|
208
|
-
|
|
209
173
|
self.builder = builder
|
|
210
174
|
|
|
211
175
|
offsets = []
|
|
@@ -261,7 +225,11 @@ class Predicate:
|
|
|
261
225
|
elif prev_field_name != field_name:
|
|
262
226
|
raise NotImplementedError(self.expr)
|
|
263
227
|
|
|
264
|
-
|
|
228
|
+
node = self.nodes_map[field_name]
|
|
229
|
+
# TODO: support predicate pushdown for leaf nodes (ORION-160338)
|
|
230
|
+
if node.children:
|
|
231
|
+
raise NotImplementedError(node.field) # no predicate pushdown for nested columns
|
|
232
|
+
column_offset = self.build_column(position=node.index)
|
|
265
233
|
field = self.schema.field(field_name)
|
|
266
234
|
for literal in literals:
|
|
267
235
|
args_offsets = [column_offset]
|
|
@@ -839,12 +807,13 @@ class VastdbApi:
|
|
|
839
807
|
return prefix
|
|
840
808
|
|
|
841
809
|
def _fill_common_headers(self, txid=0, client_tags=[], version_id=1):
|
|
842
|
-
common_headers = {
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
810
|
+
common_headers = {
|
|
811
|
+
'tabular-txid': str(txid),
|
|
812
|
+
'tabular-api-version-id': str(version_id),
|
|
813
|
+
'tabular-client-name': 'tabular-api'
|
|
814
|
+
}
|
|
846
815
|
|
|
847
|
-
return common_headers
|
|
816
|
+
return common_headers | {f'tabular-client-tags-{index}': tag for index, tag in enumerate(client_tags)}
|
|
848
817
|
|
|
849
818
|
def _check_res(self, res, cmd="", expected_retvals=[]):
|
|
850
819
|
if exc := errors.from_response(res):
|
|
@@ -952,8 +921,7 @@ class VastdbApi:
|
|
|
952
921
|
res_headers = res.headers
|
|
953
922
|
next_key = int(res_headers['tabular-next-key'])
|
|
954
923
|
is_truncated = res_headers['tabular-is-truncated'] == 'true'
|
|
955
|
-
|
|
956
|
-
lists = list_schemas.GetRootAs(flatbuf)
|
|
924
|
+
lists = list_schemas.GetRootAs(res.content)
|
|
957
925
|
bucket_name = lists.BucketName().decode()
|
|
958
926
|
if not bucket.startswith(bucket_name):
|
|
959
927
|
raise ValueError(f'bucket: {bucket} did not start from {bucket_name}')
|
|
@@ -976,8 +944,7 @@ class VastdbApi:
|
|
|
976
944
|
res = self.session.get(self._api_prefix(bucket=bucket, command="list", url_params=url_params), headers={}, stream=True)
|
|
977
945
|
self._check_res(res, "list_snapshots")
|
|
978
946
|
|
|
979
|
-
|
|
980
|
-
xml_str = out.decode()
|
|
947
|
+
xml_str = res.content.decode()
|
|
981
948
|
xml_dict = xmltodict.parse(xml_str)
|
|
982
949
|
list_res = xml_dict['ListBucketResult']
|
|
983
950
|
is_truncated = list_res['IsTruncated'] == 'true'
|
|
@@ -1059,30 +1026,11 @@ class VastdbApi:
|
|
|
1059
1026
|
res = self.session.get(self._api_prefix(bucket=bucket, schema=schema, table=name, command="stats", url_params=url_params), headers=headers)
|
|
1060
1027
|
self._check_res(res, "get_table_stats", expected_retvals)
|
|
1061
1028
|
|
|
1062
|
-
|
|
1063
|
-
stats = get_table_stats.GetRootAs(flatbuf)
|
|
1029
|
+
stats = get_table_stats.GetRootAs(res.content)
|
|
1064
1030
|
num_rows = stats.NumRows()
|
|
1065
1031
|
size_in_bytes = stats.SizeInBytes()
|
|
1066
1032
|
is_external_rowid_alloc = stats.IsExternalRowidAlloc()
|
|
1067
|
-
endpoints = []
|
|
1068
|
-
if stats.VipsLength() == 0:
|
|
1069
|
-
endpoints.append(self.url)
|
|
1070
|
-
else:
|
|
1071
|
-
url = urllib3.util.parse_url(self.url)
|
|
1072
|
-
|
|
1073
|
-
ip_cls = IPv6Address if (stats.AddressType() == "ipv6") else IPv4Address
|
|
1074
|
-
vips = [stats.Vips(i) for i in range(stats.VipsLength())]
|
|
1075
|
-
ips = []
|
|
1076
|
-
# extract the vips into list of IPs
|
|
1077
|
-
for vip in vips:
|
|
1078
|
-
start_ip = int(ip_cls(vip.StartAddress().decode()))
|
|
1079
|
-
ips.extend(ip_cls(start_ip + i) for i in range(vip.AddressCount()))
|
|
1080
|
-
# build a list of endpoint URLs, reusing schema and port (if specified when constructing the session).
|
|
1081
|
-
# it is assumed that the client can access the returned IPs (e.g. if they are part of the VIP pool).
|
|
1082
|
-
for ip in ips:
|
|
1083
|
-
d = url._asdict()
|
|
1084
|
-
d['host'] = str(ip)
|
|
1085
|
-
endpoints.append(str(urllib3.util.Url(**d)))
|
|
1033
|
+
endpoints = [self.url] # we cannot replace the host by a VIP address in HTTPS-based URLs
|
|
1086
1034
|
return TableStatsResult(num_rows, size_in_bytes, is_external_rowid_alloc, tuple(endpoints))
|
|
1087
1035
|
|
|
1088
1036
|
def alter_table(self, bucket, schema, name, txid=0, client_tags=[], table_properties="",
|
|
@@ -1159,8 +1107,7 @@ class VastdbApi:
|
|
|
1159
1107
|
res_headers = res.headers
|
|
1160
1108
|
next_key = int(res_headers['tabular-next-key'])
|
|
1161
1109
|
is_truncated = res_headers['tabular-is-truncated'] == 'true'
|
|
1162
|
-
|
|
1163
|
-
lists = list_tables.GetRootAs(flatbuf)
|
|
1110
|
+
lists = list_tables.GetRootAs(res.content)
|
|
1164
1111
|
bucket_name = lists.BucketName().decode()
|
|
1165
1112
|
schema_name = lists.SchemaName().decode()
|
|
1166
1113
|
if not bucket.startswith(bucket_name): # ignore snapshot name
|
|
@@ -1288,11 +1235,7 @@ class VastdbApi:
|
|
|
1288
1235
|
next_key = int(res_headers['tabular-next-key'])
|
|
1289
1236
|
is_truncated = res_headers['tabular-is-truncated'] == 'true'
|
|
1290
1237
|
count = int(res_headers['tabular-list-count'])
|
|
1291
|
-
columns = []
|
|
1292
|
-
if not count_only:
|
|
1293
|
-
schema_buf = b''.join(res.iter_content(chunk_size=128))
|
|
1294
|
-
schema_out = pa.ipc.open_stream(schema_buf).schema
|
|
1295
|
-
columns = schema_out
|
|
1238
|
+
columns = [] if count_only else pa.ipc.open_stream(res.content).schema
|
|
1296
1239
|
|
|
1297
1240
|
return columns, next_key, is_truncated, count
|
|
1298
1241
|
|
|
@@ -1692,8 +1635,7 @@ class VastdbApi:
|
|
|
1692
1635
|
res = self.session.get(self._api_prefix(bucket=bucket, schema=schema, table=table, command="projection-stats", url_params=url_params),
|
|
1693
1636
|
headers=headers)
|
|
1694
1637
|
if res.status_code == 200:
|
|
1695
|
-
|
|
1696
|
-
stats = get_projection_table_stats.GetRootAs(flatbuf)
|
|
1638
|
+
stats = get_projection_table_stats.GetRootAs(res.content)
|
|
1697
1639
|
num_rows = stats.NumRows()
|
|
1698
1640
|
size_in_bytes = stats.SizeInBytes()
|
|
1699
1641
|
dirty_blocks_percentage = stats.DirtyBlocksPercentage()
|
|
@@ -1779,8 +1721,7 @@ class VastdbApi:
|
|
|
1779
1721
|
next_key = int(res_headers['tabular-next-key'])
|
|
1780
1722
|
is_truncated = res_headers['tabular-is-truncated'] == 'true'
|
|
1781
1723
|
count = int(res_headers['tabular-list-count'])
|
|
1782
|
-
|
|
1783
|
-
lists = list_projections.GetRootAs(flatbuf)
|
|
1724
|
+
lists = list_projections.GetRootAs(res.content)
|
|
1784
1725
|
bucket_name = lists.BucketName().decode()
|
|
1785
1726
|
schema_name = lists.SchemaName().decode()
|
|
1786
1727
|
table_name = lists.TableName().decode()
|
|
@@ -1827,13 +1768,8 @@ class VastdbApi:
|
|
|
1827
1768
|
next_key = int(res_headers['tabular-next-key'])
|
|
1828
1769
|
is_truncated = res_headers['tabular-is-truncated'] == 'true'
|
|
1829
1770
|
count = int(res_headers['tabular-list-count'])
|
|
1830
|
-
columns = []
|
|
1831
|
-
|
|
1832
|
-
schema_buf = b''.join(res.iter_content(chunk_size=128))
|
|
1833
|
-
schema_out = pa.ipc.open_stream(schema_buf).schema
|
|
1834
|
-
for f in schema_out:
|
|
1835
|
-
columns.append([f.name, f.type, f.metadata])
|
|
1836
|
-
# sort_type = f.metadata[b'VAST:sort_type'].decode()
|
|
1771
|
+
columns = [] if count_only else [[f.name, f.type, f.metadata] for f in
|
|
1772
|
+
pa.ipc.open_stream(res.content).schema]
|
|
1837
1773
|
|
|
1838
1774
|
return columns, next_key, is_truncated, count
|
|
1839
1775
|
|
|
@@ -31,6 +31,51 @@ class Schema:
|
|
|
31
31
|
"""VAST transaction used for this schema."""
|
|
32
32
|
return self.bucket.tx
|
|
33
33
|
|
|
34
|
+
def _subschema_full_name(self, name: str) -> str:
|
|
35
|
+
return f"{self.name}/{name}" if self.name else name
|
|
36
|
+
|
|
37
|
+
def create_schema(self, name: str, fail_if_exists=True) -> "Schema":
|
|
38
|
+
"""Create a new schema (a container of tables) under this schema."""
|
|
39
|
+
if current := self.schema(name, fail_if_missing=False):
|
|
40
|
+
if fail_if_exists:
|
|
41
|
+
raise errors.SchemaExists(self.bucket.name, name)
|
|
42
|
+
else:
|
|
43
|
+
return current
|
|
44
|
+
full_name = self._subschema_full_name(name)
|
|
45
|
+
self.tx._rpc.api.create_schema(self.bucket.name, full_name, txid=self.tx.txid)
|
|
46
|
+
log.info("Created schema: %s", full_name)
|
|
47
|
+
return self.schema(name) # type: ignore[return-value]
|
|
48
|
+
|
|
49
|
+
def schema(self, name: str, fail_if_missing=True) -> Optional["Schema"]:
|
|
50
|
+
"""Get a specific schema (a container of tables) under this schema."""
|
|
51
|
+
_bucket_name, schemas, _next_key, _is_truncated, _ = \
|
|
52
|
+
self.tx._rpc.api.list_schemas(bucket=self.bucket.name, schema=self.name, next_key=0, txid=self.tx.txid,
|
|
53
|
+
name_prefix=name, exact_match=True, max_keys=1)
|
|
54
|
+
names = [name for name, *_ in schemas]
|
|
55
|
+
log.debug("Found schemas: %s", names)
|
|
56
|
+
if not names:
|
|
57
|
+
if fail_if_missing:
|
|
58
|
+
raise errors.MissingSchema(self.bucket.name, self._subschema_full_name(name))
|
|
59
|
+
else:
|
|
60
|
+
return None
|
|
61
|
+
|
|
62
|
+
assert len(names) == 1, f"Expected to receive only a single schema, but got {len(schemas)}: ({schemas})"
|
|
63
|
+
return schema.Schema(name=self._subschema_full_name(names[0]), bucket=self.bucket)
|
|
64
|
+
|
|
65
|
+
def schemas(self, batch_size=None) -> List["Schema"]:
|
|
66
|
+
"""List child schemas."""
|
|
67
|
+
next_key = 0
|
|
68
|
+
if not batch_size:
|
|
69
|
+
batch_size = 1000
|
|
70
|
+
result: List["Schema"] = []
|
|
71
|
+
while True:
|
|
72
|
+
_bucket_name, curr_schemas, next_key, is_truncated, _ = \
|
|
73
|
+
self.tx._rpc.api.list_schemas(bucket=self.bucket.name, schema=self.name, next_key=next_key, max_keys=batch_size, txid=self.tx.txid)
|
|
74
|
+
result.extend(schema.Schema(name=self._subschema_full_name(name), bucket=self.bucket) for name, *_ in curr_schemas)
|
|
75
|
+
if not is_truncated:
|
|
76
|
+
break
|
|
77
|
+
return result
|
|
78
|
+
|
|
34
79
|
def create_table(self, table_name: str, columns: pa.Schema, fail_if_exists=True) -> "Table":
|
|
35
80
|
"""Create a new table under this schema."""
|
|
36
81
|
if current := self.table(table_name, fail_if_missing=False):
|
|
@@ -7,12 +7,15 @@ For more details see:
|
|
|
7
7
|
- [Tabular identity policy with the proper permissions](https://support.vastdata.com/s/article/UUID-14322b60-d6a2-89ac-3df0-3dfbb6974182)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
+
import logging
|
|
10
11
|
import os
|
|
11
12
|
|
|
12
13
|
import boto3
|
|
13
14
|
|
|
14
15
|
from . import errors, internal_commands, transaction
|
|
15
16
|
|
|
17
|
+
log = logging.getLogger()
|
|
18
|
+
|
|
16
19
|
|
|
17
20
|
class Features:
|
|
18
21
|
"""VAST database features - check if server is already support a feature."""
|
|
@@ -21,21 +24,34 @@ class Features:
|
|
|
21
24
|
"""Save the server version."""
|
|
22
25
|
self.vast_version = vast_version
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
self.check_imports_table = self._check(
|
|
28
|
+
"Imported objects' table feature requires 5.2+ VAST release",
|
|
29
|
+
vast_version >= (5, 2))
|
|
30
|
+
|
|
31
|
+
self.check_return_row_ids = self._check(
|
|
32
|
+
"Returning row IDs requires 5.1+ VAST release",
|
|
33
|
+
vast_version >= (5, 1))
|
|
34
|
+
|
|
35
|
+
self.check_enforce_semisorted_projection = self._check(
|
|
36
|
+
"Semi-sorted projection enforcement requires 5.1+ VAST release",
|
|
37
|
+
vast_version >= (5, 1))
|
|
38
|
+
|
|
39
|
+
def _check(self, msg, supported):
|
|
40
|
+
log.debug("%s (current version is %s): supported=%s", msg, self.vast_version, supported)
|
|
41
|
+
if not supported:
|
|
42
|
+
def fail():
|
|
43
|
+
raise errors.NotSupportedVersion(msg, self.vast_version)
|
|
44
|
+
return fail
|
|
28
45
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
raise errors.NotSupportedVersion("return_row_ids requires 5.1+", self.vast_version)
|
|
46
|
+
def noop():
|
|
47
|
+
pass
|
|
48
|
+
return noop
|
|
33
49
|
|
|
34
50
|
|
|
35
51
|
class Session:
|
|
36
52
|
"""VAST database session."""
|
|
37
53
|
|
|
38
|
-
def __init__(self, access=None, secret=None, endpoint=None):
|
|
54
|
+
def __init__(self, access=None, secret=None, endpoint=None, ssl_verify=True):
|
|
39
55
|
"""Connect to a VAST Database endpoint, using specified credentials."""
|
|
40
56
|
if access is None:
|
|
41
57
|
access = os.environ['AWS_ACCESS_KEY_ID']
|
|
@@ -44,7 +60,7 @@ class Session:
|
|
|
44
60
|
if endpoint is None:
|
|
45
61
|
endpoint = os.environ['AWS_S3_ENDPOINT_URL']
|
|
46
62
|
|
|
47
|
-
self.api = internal_commands.VastdbApi(endpoint, access, secret)
|
|
63
|
+
self.api = internal_commands.VastdbApi(endpoint, access, secret, ssl_verify=ssl_verify)
|
|
48
64
|
version_tuple = tuple(int(part) for part in self.api.vast_version.split('.'))
|
|
49
65
|
self.features = Features(version_tuple)
|
|
50
66
|
self.s3 = boto3.client('s3',
|