vastdb 0.1.2__tar.gz → 0.1.4__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.2 → vastdb-0.1.4}/CHANGELOG.md +23 -0
- {vastdb-0.1.2/vastdb.egg-info → vastdb-0.1.4}/PKG-INFO +3 -2
- {vastdb-0.1.2 → vastdb-0.1.4}/README.md +5 -2
- {vastdb-0.1.2 → vastdb-0.1.4}/requirements.txt +3 -1
- {vastdb-0.1.2 → vastdb-0.1.4}/setup.py +1 -1
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/bucket.py +20 -10
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/errors.py +43 -2
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/internal_commands.py +81 -95
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/schema.py +1 -1
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/session.py +21 -1
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/table.py +202 -34
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/tests/test_imports.py +13 -1
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/tests/test_schemas.py +1 -2
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/tests/test_tables.py +43 -2
- vastdb-0.1.4/vastdb/tests/test_util.py +39 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/tests/util.py +3 -1
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/transaction.py +19 -3
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/util.py +41 -6
- {vastdb-0.1.2 → vastdb-0.1.4/vastdb.egg-info}/PKG-INFO +3 -2
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb.egg-info/SOURCES.txt +1 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb.egg-info/requires.txt +2 -1
- {vastdb-0.1.2 → vastdb-0.1.4}/LICENSE +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/MANIFEST.in +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/setup.cfg +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/__init__.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/__init__.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/__init__.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/__init__.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/__init__.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Aggregate.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ArraySlice.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ArraySubscript.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/BinaryLiteral.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/BooleanLiteral.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Bound.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Call.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/CaseFragment.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Cast.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ConcreteBoundImpl.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ConditionalCase.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/CurrentRow.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/DateLiteral.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/DecimalLiteral.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Deref.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/DurationLiteral.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Expression.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ExpressionImpl.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/FieldIndex.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/FieldRef.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Filter.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/FixedSizeBinaryLiteral.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Float16Literal.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Float32Literal.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Float64Literal.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Following.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Frame.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Grouping.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int16Literal.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int32Literal.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int64Literal.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int8Literal.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteral.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteralDaysMilliseconds.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteralImpl.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteralMonths.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Join.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/JoinKind.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/KeyValue.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Limit.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ListLiteral.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Literal.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/LiteralColumn.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/LiteralImpl.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/LiteralRelation.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/MapKey.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/MapLiteral.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/OrderBy.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Ordering.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Plan.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Preceding.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Project.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/RelId.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Relation.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/RelationImpl.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SetOpKind.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SetOperation.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SimpleCase.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SortKey.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Source.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/StringLiteral.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/StructField.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/StructLiteral.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/TimeLiteral.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/TimestampLiteral.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt16Literal.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt32Literal.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt64Literal.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt8Literal.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Unbounded.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/WindowCall.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/__init__.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Binary.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Block.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/BodyCompression.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/BodyCompressionMethod.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Bool.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Buffer.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/CompressionType.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Date.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/DateUnit.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Decimal.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/DictionaryBatch.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/DictionaryEncoding.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/DictionaryKind.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Duration.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Endianness.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Feature.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Field.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/FieldNode.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/FixedSizeBinary.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/FixedSizeList.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/FloatingPoint.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Footer.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Int.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Interval.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/IntervalUnit.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/KeyValue.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/LargeBinary.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/LargeList.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/LargeUtf8.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/List.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Map.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Message.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/MessageHeader.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/MetadataVersion.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Null.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Precision.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/RecordBatch.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Schema.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/SparseMatrixCompressedAxis.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/SparseMatrixIndexCSX.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensor.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensorIndex.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensorIndexCOO.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensorIndexCSF.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Struct_.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Tensor.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/TensorDim.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Time.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/TimeUnit.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Timestamp.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Type.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Union.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/UnionMode.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/Utf8.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/org/apache/arrow/flatbuf/__init__.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/tabular/AlterColumnRequest.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/tabular/AlterProjectionTableRequest.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/tabular/AlterSchemaRequest.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/tabular/AlterTableRequest.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/tabular/Column.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/tabular/ColumnType.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/tabular/CreateProjectionRequest.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/tabular/CreateSchemaRequest.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/tabular/GetProjectionTableStatsResponse.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/tabular/GetTableStatsResponse.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/tabular/ImportDataRequest.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/tabular/ListProjectionsResponse.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/tabular/ListSchemasResponse.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/tabular/ListTablesResponse.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/tabular/ObjectDetails.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/tabular/S3File.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/tabular/VipRange.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vast_flatbuf/tabular/__init__.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/__init__.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/bench/__init__.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/bench/test_perf.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/conftest.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/tests/__init__.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/tests/test_duckdb.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/tests/test_nested.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/tests/test_projections.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb/tests/test_sanity.py +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb.egg-info/dependency_links.txt +0 -0
- {vastdb-0.1.2 → vastdb-0.1.4}/vastdb.egg-info/top_level.txt +0 -0
|
@@ -4,6 +4,29 @@ 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.4] (2024-05-13)
|
|
8
|
+
[0.1.4]: https://github.com/vast-data/vastdb_sdk/compare/v0.1.3...v0.1.4
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Resume `Table.select()` on HTTP 503 code
|
|
12
|
+
- Allow pushing down True/False boolean literals
|
|
13
|
+
- Support `between` predicate pushdown
|
|
14
|
+
- Support inserting wide rows (larger than 5MB)
|
|
15
|
+
|
|
16
|
+
## [0.1.3] (2024-05-05)
|
|
17
|
+
[0.1.3]: https://github.com/vast-data/vastdb_sdk/compare/v0.1.2...v0.1.3
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
- Document predicate pushdown support
|
|
21
|
+
- Access imports' table (for VAST 5.2+)
|
|
22
|
+
- Support `is_in` predicate pushdown
|
|
23
|
+
- Document `table.py`
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
- Freeze `ibis` dependency at 8.0.0
|
|
27
|
+
- Support snapshot-based access
|
|
28
|
+
- Optimize RecordBatch slicing
|
|
29
|
+
|
|
7
30
|
## [0.1.2] (2024-04-25)
|
|
8
31
|
[0.1.2]: https://github.com/vast-data/vastdb_sdk/compare/v0.1.1...v0.1.2
|
|
9
32
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: vastdb
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: VAST Data SDK
|
|
5
5
|
Home-page: https://github.com/vast-data/vastdb_sdk
|
|
6
6
|
Author: VAST DATA
|
|
@@ -21,10 +21,11 @@ License-File: LICENSE
|
|
|
21
21
|
Requires-Dist: aws-requests-auth
|
|
22
22
|
Requires-Dist: boto3
|
|
23
23
|
Requires-Dist: flatbuffers
|
|
24
|
-
Requires-Dist: ibis-framework
|
|
24
|
+
Requires-Dist: ibis-framework==8.0.0
|
|
25
25
|
Requires-Dist: pyarrow
|
|
26
26
|
Requires-Dist: requests
|
|
27
27
|
Requires-Dist: xmltodict
|
|
28
|
+
Requires-Dist: backoff==2.2.1
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
`vastdb` is a Python-based SDK designed for interacting
|
|
@@ -86,6 +86,8 @@ Our SDK supports predicate and projection pushdown:
|
|
|
86
86
|
table.select(predicate=table['c3'].contains('substring'))
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
+
See [here for more details](docs/predicate.md).
|
|
90
|
+
|
|
89
91
|
## Import a single Parquet file via S3 protocol
|
|
90
92
|
|
|
91
93
|
It is possible to efficiently create a table from a Parquet file (without copying it via the client):
|
|
@@ -150,10 +152,11 @@ p.drop()
|
|
|
150
152
|
|
|
151
153
|
## Snapshots
|
|
152
154
|
|
|
153
|
-
It is possible to
|
|
155
|
+
It is possible to use [snapshots](https://vastdata.com/blog/bringing-snapshots-to-vasts-element-store) for accessing the Database:
|
|
154
156
|
|
|
155
157
|
```python
|
|
156
|
-
|
|
158
|
+
snaps = bucket.list_snapshots()
|
|
159
|
+
batches = snaps[0].schema('schema-name').table('table-name').select()
|
|
157
160
|
```
|
|
158
161
|
|
|
159
162
|
## VAST Catalog
|
|
@@ -16,14 +16,6 @@ if TYPE_CHECKING:
|
|
|
16
16
|
log = logging.getLogger(__name__)
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
@dataclass
|
|
20
|
-
class Snapshot:
|
|
21
|
-
"""VAST bucket-level snapshot."""
|
|
22
|
-
|
|
23
|
-
name: str
|
|
24
|
-
bucket: "Bucket"
|
|
25
|
-
|
|
26
|
-
|
|
27
19
|
@dataclass
|
|
28
20
|
class Bucket:
|
|
29
21
|
"""VAST bucket."""
|
|
@@ -73,7 +65,22 @@ class Bucket:
|
|
|
73
65
|
|
|
74
66
|
return [schema.Schema(name=name, bucket=self) for name, *_ in schemas]
|
|
75
67
|
|
|
76
|
-
def
|
|
68
|
+
def snapshot(self, name, fail_if_missing=True) -> Optional["Bucket"]:
|
|
69
|
+
"""Get snapshot by name (if exists)."""
|
|
70
|
+
snapshots, _is_truncated, _next_key = \
|
|
71
|
+
self.tx._rpc.api.list_snapshots(bucket=self.name, name_prefix=name, max_keys=1)
|
|
72
|
+
|
|
73
|
+
expected_name = f".snapshot/{name}"
|
|
74
|
+
exists = snapshots and snapshots[0] == expected_name + "/"
|
|
75
|
+
if not exists:
|
|
76
|
+
if fail_if_missing:
|
|
77
|
+
raise errors.MissingSnapshot(self.name, expected_name)
|
|
78
|
+
else:
|
|
79
|
+
return None
|
|
80
|
+
|
|
81
|
+
return Bucket(name=f'{self.name}/{expected_name}', tx=self.tx)
|
|
82
|
+
|
|
83
|
+
def snapshots(self) -> List["Bucket"]:
|
|
77
84
|
"""List bucket's snapshots."""
|
|
78
85
|
snapshots = []
|
|
79
86
|
next_key = 0
|
|
@@ -86,4 +93,7 @@ class Bucket:
|
|
|
86
93
|
if not is_truncated:
|
|
87
94
|
break
|
|
88
95
|
|
|
89
|
-
return [
|
|
96
|
+
return [
|
|
97
|
+
Bucket(name=f'{self.name}/{snapshot.strip("/")}', tx=self.tx)
|
|
98
|
+
for snapshot in snapshots
|
|
99
|
+
]
|
|
@@ -71,6 +71,10 @@ class ServiceUnavailable(HttpError):
|
|
|
71
71
|
pass
|
|
72
72
|
|
|
73
73
|
|
|
74
|
+
class Slowdown(ServiceUnavailable):
|
|
75
|
+
pass
|
|
76
|
+
|
|
77
|
+
|
|
74
78
|
class UnexpectedError(HttpError):
|
|
75
79
|
pass
|
|
76
80
|
|
|
@@ -85,6 +89,10 @@ class InvalidArgument(Exception):
|
|
|
85
89
|
pass
|
|
86
90
|
|
|
87
91
|
|
|
92
|
+
class TooWideRow(InvalidArgument):
|
|
93
|
+
pass
|
|
94
|
+
|
|
95
|
+
|
|
88
96
|
class Missing(Exception):
|
|
89
97
|
pass
|
|
90
98
|
|
|
@@ -93,11 +101,25 @@ class MissingTransaction(Missing):
|
|
|
93
101
|
pass
|
|
94
102
|
|
|
95
103
|
|
|
104
|
+
class MissingRowIdColumn(Missing):
|
|
105
|
+
pass
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class NotSupported(Exception):
|
|
109
|
+
pass
|
|
110
|
+
|
|
111
|
+
|
|
96
112
|
@dataclass
|
|
97
113
|
class MissingBucket(Missing):
|
|
98
114
|
bucket: str
|
|
99
115
|
|
|
100
116
|
|
|
117
|
+
@dataclass
|
|
118
|
+
class MissingSnapshot(Missing):
|
|
119
|
+
bucket: str
|
|
120
|
+
snapshot: str
|
|
121
|
+
|
|
122
|
+
|
|
101
123
|
@dataclass
|
|
102
124
|
class MissingSchema(Missing):
|
|
103
125
|
bucket: str
|
|
@@ -136,6 +158,25 @@ class TableExists(Exists):
|
|
|
136
158
|
table: str
|
|
137
159
|
|
|
138
160
|
|
|
161
|
+
@dataclass
|
|
162
|
+
class NotSupportedCommand(NotSupported):
|
|
163
|
+
bucket: str
|
|
164
|
+
schema: str
|
|
165
|
+
table: str
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
@dataclass
|
|
169
|
+
class NotSupportedVersion(NotSupported):
|
|
170
|
+
err_msg: str
|
|
171
|
+
version: str
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def handle_unavailable(**kwargs):
|
|
175
|
+
if kwargs['code'] == 'SlowDown':
|
|
176
|
+
raise Slowdown(**kwargs)
|
|
177
|
+
raise ServiceUnavailable(**kwargs)
|
|
178
|
+
|
|
179
|
+
|
|
139
180
|
ERROR_TYPES_MAP = {
|
|
140
181
|
HttpStatus.BAD_REQUEST: BadRequest,
|
|
141
182
|
HttpStatus.FOBIDDEN: Forbidden,
|
|
@@ -145,7 +186,7 @@ ERROR_TYPES_MAP = {
|
|
|
145
186
|
HttpStatus.CONFLICT: Conflict,
|
|
146
187
|
HttpStatus.INTERNAL_SERVER_ERROR: InternalServerError,
|
|
147
188
|
HttpStatus.NOT_IMPLEMENTED: NotImplemented,
|
|
148
|
-
HttpStatus.SERVICE_UNAVAILABLE:
|
|
189
|
+
HttpStatus.SERVICE_UNAVAILABLE: handle_unavailable,
|
|
149
190
|
}
|
|
150
191
|
|
|
151
192
|
|
|
@@ -178,4 +219,4 @@ def from_response(res: requests.Response):
|
|
|
178
219
|
log.warning("RPC failed: %s", kwargs)
|
|
179
220
|
status = HttpStatus(res.status_code)
|
|
180
221
|
error_type = ERROR_TYPES_MAP.get(status, UnexpectedError)
|
|
181
|
-
|
|
222
|
+
return error_type(**kwargs) # type: ignore
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import itertools
|
|
2
2
|
import json
|
|
3
3
|
import logging
|
|
4
|
-
import math
|
|
5
4
|
import re
|
|
6
5
|
import struct
|
|
7
6
|
import urllib.parse
|
|
@@ -179,9 +178,11 @@ class Predicate:
|
|
|
179
178
|
)
|
|
180
179
|
from ibis.expr.operations.logical import (
|
|
181
180
|
And,
|
|
181
|
+
Between,
|
|
182
182
|
Equals,
|
|
183
183
|
Greater,
|
|
184
184
|
GreaterEqual,
|
|
185
|
+
InValues,
|
|
185
186
|
Less,
|
|
186
187
|
LessEqual,
|
|
187
188
|
Not,
|
|
@@ -200,6 +201,7 @@ class Predicate:
|
|
|
200
201
|
IsNull: self.build_is_null,
|
|
201
202
|
Not: self.build_is_not_null,
|
|
202
203
|
StringContains: self.build_match_substring,
|
|
204
|
+
Between: self.build_between,
|
|
203
205
|
}
|
|
204
206
|
|
|
205
207
|
positions_map = dict((f.name, index) for index, f in enumerate(self.schema)) # TODO: BFS
|
|
@@ -219,40 +221,60 @@ class Predicate:
|
|
|
219
221
|
prev_field_name = None
|
|
220
222
|
for inner_op in or_args:
|
|
221
223
|
_logger.debug('inner_op %s', inner_op)
|
|
222
|
-
|
|
224
|
+
op_type = type(inner_op)
|
|
225
|
+
builder_func: Any = builder_map.get(op_type)
|
|
223
226
|
if not builder_func:
|
|
224
|
-
|
|
227
|
+
if op_type == InValues:
|
|
228
|
+
builder_func = self.build_equal
|
|
229
|
+
else:
|
|
230
|
+
raise NotImplementedError(self.expr)
|
|
225
231
|
|
|
226
232
|
if builder_func == self.build_is_null:
|
|
227
233
|
column, = inner_op.args
|
|
228
|
-
|
|
234
|
+
literals = (None,)
|
|
229
235
|
elif builder_func == self.build_is_not_null:
|
|
230
236
|
not_arg, = inner_op.args
|
|
231
237
|
# currently we only support not is_null, checking we really got is_null under the not:
|
|
232
238
|
if not builder_map.get(type(not_arg)) == self.build_is_null:
|
|
233
|
-
raise NotImplementedError(
|
|
239
|
+
raise NotImplementedError(self.expr)
|
|
234
240
|
column, = not_arg.args
|
|
235
|
-
|
|
241
|
+
literals = (None,)
|
|
242
|
+
elif builder_func == self.build_between:
|
|
243
|
+
column, lower, upper = inner_op.args
|
|
244
|
+
literals = (None,)
|
|
236
245
|
else:
|
|
237
|
-
column,
|
|
238
|
-
if
|
|
239
|
-
|
|
246
|
+
column, arg = inner_op.args
|
|
247
|
+
if isinstance(arg, tuple):
|
|
248
|
+
literals = arg
|
|
249
|
+
else:
|
|
250
|
+
literals = (arg,)
|
|
251
|
+
for literal in literals:
|
|
252
|
+
if not isinstance(literal, Literal):
|
|
253
|
+
raise NotImplementedError(self.expr)
|
|
240
254
|
|
|
241
255
|
if not isinstance(column, TableColumn):
|
|
242
|
-
raise NotImplementedError(
|
|
256
|
+
raise NotImplementedError(self.expr)
|
|
243
257
|
|
|
244
258
|
field_name = column.name
|
|
245
259
|
if prev_field_name is None:
|
|
246
260
|
prev_field_name = field_name
|
|
247
261
|
elif prev_field_name != field_name:
|
|
248
|
-
raise NotImplementedError(
|
|
262
|
+
raise NotImplementedError(self.expr)
|
|
249
263
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
args_offsets
|
|
264
|
+
column_offset = self.build_column(position=positions_map[field_name])
|
|
265
|
+
field = self.schema.field(field_name)
|
|
266
|
+
for literal in literals:
|
|
267
|
+
args_offsets = [column_offset]
|
|
268
|
+
if literal is not None:
|
|
269
|
+
args_offsets.append(self.build_literal(field=field, value=literal.value))
|
|
270
|
+
if builder_func == self.build_between:
|
|
271
|
+
args_offsets.append(self.build_literal(field=field, value=lower.value))
|
|
272
|
+
args_offsets.append(self.build_literal(field=field, value=upper.value))
|
|
254
273
|
|
|
255
|
-
|
|
274
|
+
inner_offsets.append(builder_func(*args_offsets))
|
|
275
|
+
|
|
276
|
+
if not inner_offsets:
|
|
277
|
+
raise NotImplementedError(self.expr) # an empty OR is equivalent to a 'FALSE' literal
|
|
256
278
|
|
|
257
279
|
domain_offset = self.build_or(inner_offsets)
|
|
258
280
|
offsets.append(domain_offset)
|
|
@@ -542,6 +564,13 @@ class Predicate:
|
|
|
542
564
|
def build_match_substring(self, column: int, literal: int):
|
|
543
565
|
return self.build_function('match_substring', column, literal)
|
|
544
566
|
|
|
567
|
+
def build_between(self, column: int, lower: int, upper: int):
|
|
568
|
+
offsets = [
|
|
569
|
+
self.build_greater_equal(column, lower),
|
|
570
|
+
self.build_less_equal(column, upper),
|
|
571
|
+
]
|
|
572
|
+
return self.build_and(offsets)
|
|
573
|
+
|
|
545
574
|
|
|
546
575
|
class FieldNodesState:
|
|
547
576
|
def __init__(self) -> None:
|
|
@@ -719,20 +748,6 @@ def _parse_table_info(obj):
|
|
|
719
748
|
return TableInfo(name, properties, handle, num_rows, used_bytes)
|
|
720
749
|
|
|
721
750
|
|
|
722
|
-
def build_record_batch(column_info, column_values):
|
|
723
|
-
fields = [pa.field(column_name, column_type) for column_type, column_name in column_info]
|
|
724
|
-
schema = pa.schema(fields)
|
|
725
|
-
arrays = [pa.array(column_values[column_type], type=column_type) for column_type, _ in column_info]
|
|
726
|
-
batch = pa.record_batch(arrays, schema)
|
|
727
|
-
return serialize_record_batch(batch)
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
def serialize_record_batch(batch):
|
|
731
|
-
sink = pa.BufferOutputStream()
|
|
732
|
-
with pa.ipc.new_stream(sink, batch.schema) as writer:
|
|
733
|
-
writer.write(batch)
|
|
734
|
-
return sink.getvalue()
|
|
735
|
-
|
|
736
751
|
# Results that returns from tablestats
|
|
737
752
|
|
|
738
753
|
|
|
@@ -952,26 +967,27 @@ class VastdbApi:
|
|
|
952
967
|
|
|
953
968
|
return bucket_name, schemas, next_key, is_truncated, count
|
|
954
969
|
|
|
955
|
-
def list_snapshots(self, bucket, max_keys=1000, next_token=None,
|
|
970
|
+
def list_snapshots(self, bucket, max_keys=1000, next_token=None, name_prefix=''):
|
|
956
971
|
next_token = next_token or ''
|
|
957
|
-
|
|
958
|
-
url_params = {'list_type': '2', 'prefix': '.snapshot/', 'delimiter': '/', 'max_keys': str(max_keys)}
|
|
972
|
+
url_params = {'list_type': '2', 'prefix': '.snapshot/' + name_prefix, 'delimiter': '/', 'max_keys': str(max_keys)}
|
|
959
973
|
if next_token:
|
|
960
974
|
url_params['continuation-token'] = next_token
|
|
961
975
|
|
|
962
976
|
res = self.session.get(self._api_prefix(bucket=bucket, command="list", url_params=url_params), headers={}, stream=True)
|
|
963
|
-
self._check_res(res, "list_snapshots"
|
|
964
|
-
if res.status_code == 200:
|
|
965
|
-
out = b''.join(res.iter_content(chunk_size=128))
|
|
966
|
-
xml_str = out.decode()
|
|
967
|
-
xml_dict = xmltodict.parse(xml_str)
|
|
968
|
-
list_res = xml_dict['ListBucketResult']
|
|
969
|
-
is_truncated = list_res['IsTruncated'] == 'true'
|
|
970
|
-
marker = list_res['Marker']
|
|
971
|
-
common_prefixes = list_res['CommonPrefixes'] if 'CommonPrefixes' in list_res else []
|
|
972
|
-
snapshots = [v['Prefix'] for v in common_prefixes]
|
|
977
|
+
self._check_res(res, "list_snapshots")
|
|
973
978
|
|
|
974
|
-
|
|
979
|
+
out = b''.join(res.iter_content(chunk_size=128))
|
|
980
|
+
xml_str = out.decode()
|
|
981
|
+
xml_dict = xmltodict.parse(xml_str)
|
|
982
|
+
list_res = xml_dict['ListBucketResult']
|
|
983
|
+
is_truncated = list_res['IsTruncated'] == 'true'
|
|
984
|
+
marker = list_res['Marker']
|
|
985
|
+
common_prefixes = list_res.get('CommonPrefixes', [])
|
|
986
|
+
if isinstance(common_prefixes, dict): # in case there is a single snapshot
|
|
987
|
+
common_prefixes = [common_prefixes]
|
|
988
|
+
snapshots = [v['Prefix'] for v in common_prefixes]
|
|
989
|
+
|
|
990
|
+
return snapshots, is_truncated, marker
|
|
975
991
|
|
|
976
992
|
def create_table(self, bucket, schema, name, arrow_schema, txid=0, client_tags=[], expected_retvals=[],
|
|
977
993
|
topic_partitions=0, create_imports_table=False, use_external_row_ids_allocation=False):
|
|
@@ -1030,7 +1046,7 @@ class VastdbApi:
|
|
|
1030
1046
|
# create the table
|
|
1031
1047
|
return self.create_table(bucket, schema, name, arrow_schema, txid, client_tags, expected_retvals)
|
|
1032
1048
|
|
|
1033
|
-
def get_table_stats(self, bucket, schema, name, txid=0, client_tags=[], expected_retvals=[]):
|
|
1049
|
+
def get_table_stats(self, bucket, schema, name, txid=0, client_tags=[], expected_retvals=[], imports_table_stats=False):
|
|
1034
1050
|
"""
|
|
1035
1051
|
GET /mybucket/myschema/mytable?stats HTTP/1.1
|
|
1036
1052
|
tabular-txid: TransactionId
|
|
@@ -1039,7 +1055,8 @@ class VastdbApi:
|
|
|
1039
1055
|
The Command will return the statistics in flatbuf format
|
|
1040
1056
|
"""
|
|
1041
1057
|
headers = self._fill_common_headers(txid=txid, client_tags=client_tags)
|
|
1042
|
-
|
|
1058
|
+
url_params = {'sub-table': IMPORTED_OBJECTS_TABLE_NAME} if imports_table_stats else {}
|
|
1059
|
+
res = self.session.get(self._api_prefix(bucket=bucket, schema=schema, table=name, command="stats", url_params=url_params), headers=headers)
|
|
1043
1060
|
self._check_res(res, "get_table_stats", expected_retvals)
|
|
1044
1061
|
|
|
1045
1062
|
flatbuf = b''.join(res.iter_content(chunk_size=128))
|
|
@@ -1527,11 +1544,18 @@ class VastdbApi:
|
|
|
1527
1544
|
if response.status_code != 200:
|
|
1528
1545
|
return response
|
|
1529
1546
|
|
|
1547
|
+
ALLOWED_IMPORT_STATES = {
|
|
1548
|
+
'Success',
|
|
1549
|
+
'TabularInProgress',
|
|
1550
|
+
'TabularAlreadyImported',
|
|
1551
|
+
'TabularImportNotStarted',
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1530
1554
|
chunk_size = 1024
|
|
1531
1555
|
for chunk in response.iter_content(chunk_size=chunk_size):
|
|
1532
1556
|
chunk_dict = json.loads(chunk)
|
|
1533
1557
|
_logger.debug("import data chunk=%s, result: %s", chunk_dict, chunk_dict['res'])
|
|
1534
|
-
if chunk_dict['res']
|
|
1558
|
+
if chunk_dict['res'] not in ALLOWED_IMPORT_STATES:
|
|
1535
1559
|
raise errors.ImportFilesError(
|
|
1536
1560
|
f"Encountered an error during import_data. status: {chunk_dict['res']}, "
|
|
1537
1561
|
f"error message: {chunk_dict['err_msg'] or 'Unexpected error'} during import of "
|
|
@@ -1555,48 +1579,6 @@ class VastdbApi:
|
|
|
1555
1579
|
|
|
1556
1580
|
return self._check_res(res, "import_data", expected_retvals)
|
|
1557
1581
|
|
|
1558
|
-
def _record_batch_slices(self, batch, rows_per_slice=None):
|
|
1559
|
-
max_slice_size_in_bytes = int(0.9 * 5 * 1024 * 1024) # 0.9 * 5MB
|
|
1560
|
-
batch_len = len(batch)
|
|
1561
|
-
serialized_batch = serialize_record_batch(batch)
|
|
1562
|
-
batch_size_in_bytes = len(serialized_batch)
|
|
1563
|
-
_logger.debug('max_slice_size_in_bytes=%d batch_len=%d batch_size_in_bytes=%d',
|
|
1564
|
-
max_slice_size_in_bytes, batch_len, batch_size_in_bytes)
|
|
1565
|
-
|
|
1566
|
-
if not rows_per_slice:
|
|
1567
|
-
if batch_size_in_bytes < max_slice_size_in_bytes:
|
|
1568
|
-
rows_per_slice = batch_len
|
|
1569
|
-
else:
|
|
1570
|
-
rows_per_slice = int(0.9 * batch_len * max_slice_size_in_bytes / batch_size_in_bytes)
|
|
1571
|
-
|
|
1572
|
-
done_slicing = False
|
|
1573
|
-
while not done_slicing:
|
|
1574
|
-
# Attempt slicing according to the current rows_per_slice
|
|
1575
|
-
offset = 0
|
|
1576
|
-
serialized_slices = []
|
|
1577
|
-
for i in range(math.ceil(batch_len / rows_per_slice)):
|
|
1578
|
-
offset = rows_per_slice * i
|
|
1579
|
-
if offset >= batch_len:
|
|
1580
|
-
done_slicing = True
|
|
1581
|
-
break
|
|
1582
|
-
slice_batch = batch.slice(offset, rows_per_slice)
|
|
1583
|
-
serialized_slice_batch = serialize_record_batch(slice_batch)
|
|
1584
|
-
sizeof_serialized_slice_batch = len(serialized_slice_batch)
|
|
1585
|
-
|
|
1586
|
-
if sizeof_serialized_slice_batch <= max_slice_size_in_bytes:
|
|
1587
|
-
serialized_slices.append(serialized_slice_batch)
|
|
1588
|
-
else:
|
|
1589
|
-
_logger.info(f'Using rows_per_slice {rows_per_slice} slice {i} size {sizeof_serialized_slice_batch} exceeds {max_slice_size_in_bytes} bytes, trying smaller rows_per_slice')
|
|
1590
|
-
# We have a slice that is too large
|
|
1591
|
-
rows_per_slice = int(rows_per_slice / 2)
|
|
1592
|
-
if rows_per_slice < 1:
|
|
1593
|
-
raise ValueError('cannot decrease batch size below 1 row')
|
|
1594
|
-
break
|
|
1595
|
-
else:
|
|
1596
|
-
done_slicing = True
|
|
1597
|
-
|
|
1598
|
-
return serialized_slices
|
|
1599
|
-
|
|
1600
1582
|
def insert_rows(self, bucket, schema, table, record_batch, txid=0, client_tags=[], expected_retvals=[]):
|
|
1601
1583
|
"""
|
|
1602
1584
|
POST /mybucket/myschema/mytable?rows HTTP/1.1
|
|
@@ -1611,8 +1593,7 @@ class VastdbApi:
|
|
|
1611
1593
|
headers['Content-Length'] = str(len(record_batch))
|
|
1612
1594
|
res = self.session.post(self._api_prefix(bucket=bucket, schema=schema, table=table, command="rows"),
|
|
1613
1595
|
data=record_batch, headers=headers, stream=True)
|
|
1614
|
-
self._check_res(res, "insert_rows", expected_retvals)
|
|
1615
|
-
res.raw.read() # flush the response
|
|
1596
|
+
return self._check_res(res, "insert_rows", expected_retvals)
|
|
1616
1597
|
|
|
1617
1598
|
def update_rows(self, bucket, schema, table, record_batch, txid=0, client_tags=[], expected_retvals=[]):
|
|
1618
1599
|
"""
|
|
@@ -2140,6 +2121,13 @@ class QueryDataRequest:
|
|
|
2140
2121
|
self.response_parser = response_parser
|
|
2141
2122
|
|
|
2142
2123
|
|
|
2124
|
+
def get_response_schema(schema: 'pa.Schema' = pa.schema([]), field_names: Optional[List[str]] = None):
|
|
2125
|
+
if field_names is None:
|
|
2126
|
+
field_names = [field.name for field in schema]
|
|
2127
|
+
|
|
2128
|
+
return pa.schema([schema.field(name) for name in field_names])
|
|
2129
|
+
|
|
2130
|
+
|
|
2143
2131
|
def build_query_data_request(schema: 'pa.Schema' = pa.schema([]), predicate: ibis.expr.types.BooleanColumn = None, field_names: Optional[List[str]] = None):
|
|
2144
2132
|
builder = flatbuffers.Builder(1024)
|
|
2145
2133
|
|
|
@@ -2160,13 +2148,11 @@ def build_query_data_request(schema: 'pa.Schema' = pa.schema([]), predicate: ibi
|
|
|
2160
2148
|
filter_obj = predicate.serialize(builder)
|
|
2161
2149
|
|
|
2162
2150
|
parser = QueryDataParser(schema)
|
|
2163
|
-
fields_map = {node.field.name: node.field for node in parser.nodes}
|
|
2164
2151
|
leaves_map = {node.field.name: [leaf.index for leaf in node._iter_leaves()] for node in parser.nodes}
|
|
2165
2152
|
|
|
2166
|
-
|
|
2167
|
-
|
|
2153
|
+
response_schema = get_response_schema(schema, field_names)
|
|
2154
|
+
field_names = [field.name for field in response_schema]
|
|
2168
2155
|
|
|
2169
|
-
response_schema = pa.schema([fields_map[name] for name in field_names])
|
|
2170
2156
|
projection_fields = []
|
|
2171
2157
|
for field_name in field_names:
|
|
2172
2158
|
# TODO: only root-level projection pushdown is supported (i.e. no support for SELECT s.x FROM t)
|
|
@@ -87,4 +87,4 @@ class Schema:
|
|
|
87
87
|
|
|
88
88
|
def _parse_table_info(table_info, schema: "schema.Schema"):
|
|
89
89
|
stats = table.TableStats(num_rows=table_info.num_rows, size_in_bytes=table_info.size_in_bytes)
|
|
90
|
-
return table.Table(name=table_info.name, schema=schema, handle=int(table_info.handle), stats=stats)
|
|
90
|
+
return table.Table(name=table_info.name, schema=schema, handle=int(table_info.handle), stats=stats, _imports_table=False)
|
|
@@ -11,7 +11,25 @@ import os
|
|
|
11
11
|
|
|
12
12
|
import boto3
|
|
13
13
|
|
|
14
|
-
from . import internal_commands, transaction
|
|
14
|
+
from . import errors, internal_commands, transaction
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Features:
|
|
18
|
+
"""VAST database features - check if server is already support a feature."""
|
|
19
|
+
|
|
20
|
+
def __init__(self, vast_version):
|
|
21
|
+
"""Save the server version."""
|
|
22
|
+
self.vast_version = vast_version
|
|
23
|
+
|
|
24
|
+
def check_imports_table(self):
|
|
25
|
+
"""Check if the feature that support imports table is supported."""
|
|
26
|
+
if self.vast_version < (5, 2):
|
|
27
|
+
raise errors.NotSupportedVersion("import_table requires 5.2+", self.vast_version)
|
|
28
|
+
|
|
29
|
+
def check_return_row_ids(self):
|
|
30
|
+
"""Check if insert/update/delete can return the row_ids."""
|
|
31
|
+
if self.vast_version < (5, 1):
|
|
32
|
+
raise errors.NotSupportedVersion("return_row_ids requires 5.1+", self.vast_version)
|
|
15
33
|
|
|
16
34
|
|
|
17
35
|
class Session:
|
|
@@ -27,6 +45,8 @@ class Session:
|
|
|
27
45
|
endpoint = os.environ['AWS_S3_ENDPOINT_URL']
|
|
28
46
|
|
|
29
47
|
self.api = internal_commands.VastdbApi(endpoint, access, secret)
|
|
48
|
+
version_tuple = tuple(int(part) for part in self.api.vast_version.split('.'))
|
|
49
|
+
self.features = Features(version_tuple)
|
|
30
50
|
self.s3 = boto3.client('s3',
|
|
31
51
|
aws_access_key_id=access,
|
|
32
52
|
aws_secret_access_key=secret,
|