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.
Files changed (187) hide show
  1. {vastdb-0.1.4 → vastdb-0.1.6}/CHANGELOG.md +25 -0
  2. {vastdb-0.1.4/vastdb.egg-info → vastdb-0.1.6}/PKG-INFO +1 -1
  3. {vastdb-0.1.4 → vastdb-0.1.6}/README.md +8 -4
  4. {vastdb-0.1.4 → vastdb-0.1.6}/setup.py +3 -2
  5. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/bench/test_perf.py +1 -2
  6. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/bucket.py +12 -37
  7. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/conftest.py +13 -4
  8. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/errors.py +5 -1
  9. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/internal_commands.py +26 -90
  10. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/schema.py +45 -0
  11. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/session.py +26 -10
  12. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/table.py +48 -8
  13. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/tests/test_imports.py +3 -3
  14. vastdb-0.1.6/vastdb/tests/test_nested.py +102 -0
  15. vastdb-0.1.6/vastdb/tests/test_projections.py +121 -0
  16. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/tests/test_schemas.py +49 -0
  17. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/tests/test_tables.py +123 -95
  18. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/transaction.py +24 -15
  19. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/util.py +1 -0
  20. {vastdb-0.1.4 → vastdb-0.1.6/vastdb.egg-info}/PKG-INFO +1 -1
  21. vastdb-0.1.4/vastdb/tests/test_nested.py +0 -28
  22. vastdb-0.1.4/vastdb/tests/test_projections.py +0 -43
  23. {vastdb-0.1.4 → vastdb-0.1.6}/LICENSE +0 -0
  24. {vastdb-0.1.4 → vastdb-0.1.6}/MANIFEST.in +0 -0
  25. {vastdb-0.1.4 → vastdb-0.1.6}/requirements.txt +0 -0
  26. {vastdb-0.1.4 → vastdb-0.1.6}/setup.cfg +0 -0
  27. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/__init__.py +0 -0
  28. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/__init__.py +0 -0
  29. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/__init__.py +0 -0
  30. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/__init__.py +0 -0
  31. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/__init__.py +0 -0
  32. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Aggregate.py +0 -0
  33. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ArraySlice.py +0 -0
  34. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ArraySubscript.py +0 -0
  35. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/BinaryLiteral.py +0 -0
  36. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/BooleanLiteral.py +0 -0
  37. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Bound.py +0 -0
  38. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Call.py +0 -0
  39. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/CaseFragment.py +0 -0
  40. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Cast.py +0 -0
  41. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ConcreteBoundImpl.py +0 -0
  42. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ConditionalCase.py +0 -0
  43. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/CurrentRow.py +0 -0
  44. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/DateLiteral.py +0 -0
  45. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/DecimalLiteral.py +0 -0
  46. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Deref.py +0 -0
  47. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/DurationLiteral.py +0 -0
  48. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Expression.py +0 -0
  49. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ExpressionImpl.py +0 -0
  50. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/FieldIndex.py +0 -0
  51. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/FieldRef.py +0 -0
  52. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Filter.py +0 -0
  53. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/FixedSizeBinaryLiteral.py +0 -0
  54. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Float16Literal.py +0 -0
  55. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Float32Literal.py +0 -0
  56. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Float64Literal.py +0 -0
  57. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Following.py +0 -0
  58. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Frame.py +0 -0
  59. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Grouping.py +0 -0
  60. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int16Literal.py +0 -0
  61. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int32Literal.py +0 -0
  62. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int64Literal.py +0 -0
  63. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int8Literal.py +0 -0
  64. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteral.py +0 -0
  65. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteralDaysMilliseconds.py +0 -0
  66. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteralImpl.py +0 -0
  67. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteralMonths.py +0 -0
  68. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Join.py +0 -0
  69. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/JoinKind.py +0 -0
  70. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/KeyValue.py +0 -0
  71. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Limit.py +0 -0
  72. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ListLiteral.py +0 -0
  73. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Literal.py +0 -0
  74. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/LiteralColumn.py +0 -0
  75. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/LiteralImpl.py +0 -0
  76. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/LiteralRelation.py +0 -0
  77. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/MapKey.py +0 -0
  78. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/MapLiteral.py +0 -0
  79. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/OrderBy.py +0 -0
  80. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Ordering.py +0 -0
  81. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Plan.py +0 -0
  82. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Preceding.py +0 -0
  83. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Project.py +0 -0
  84. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/RelId.py +0 -0
  85. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Relation.py +0 -0
  86. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/RelationImpl.py +0 -0
  87. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SetOpKind.py +0 -0
  88. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SetOperation.py +0 -0
  89. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SimpleCase.py +0 -0
  90. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SortKey.py +0 -0
  91. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Source.py +0 -0
  92. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/StringLiteral.py +0 -0
  93. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/StructField.py +0 -0
  94. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/StructLiteral.py +0 -0
  95. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/TimeLiteral.py +0 -0
  96. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/TimestampLiteral.py +0 -0
  97. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt16Literal.py +0 -0
  98. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt32Literal.py +0 -0
  99. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt64Literal.py +0 -0
  100. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt8Literal.py +0 -0
  101. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Unbounded.py +0 -0
  102. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/WindowCall.py +0 -0
  103. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/__init__.py +0 -0
  104. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Binary.py +0 -0
  105. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Block.py +0 -0
  106. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/BodyCompression.py +0 -0
  107. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/BodyCompressionMethod.py +0 -0
  108. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Bool.py +0 -0
  109. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Buffer.py +0 -0
  110. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/CompressionType.py +0 -0
  111. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Date.py +0 -0
  112. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/DateUnit.py +0 -0
  113. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Decimal.py +0 -0
  114. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/DictionaryBatch.py +0 -0
  115. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/DictionaryEncoding.py +0 -0
  116. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/DictionaryKind.py +0 -0
  117. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Duration.py +0 -0
  118. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Endianness.py +0 -0
  119. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Feature.py +0 -0
  120. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Field.py +0 -0
  121. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/FieldNode.py +0 -0
  122. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/FixedSizeBinary.py +0 -0
  123. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/FixedSizeList.py +0 -0
  124. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/FloatingPoint.py +0 -0
  125. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Footer.py +0 -0
  126. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Int.py +0 -0
  127. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Interval.py +0 -0
  128. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/IntervalUnit.py +0 -0
  129. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/KeyValue.py +0 -0
  130. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/LargeBinary.py +0 -0
  131. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/LargeList.py +0 -0
  132. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/LargeUtf8.py +0 -0
  133. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/List.py +0 -0
  134. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Map.py +0 -0
  135. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Message.py +0 -0
  136. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/MessageHeader.py +0 -0
  137. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/MetadataVersion.py +0 -0
  138. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Null.py +0 -0
  139. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Precision.py +0 -0
  140. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/RecordBatch.py +0 -0
  141. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Schema.py +0 -0
  142. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseMatrixCompressedAxis.py +0 -0
  143. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseMatrixIndexCSX.py +0 -0
  144. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensor.py +0 -0
  145. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensorIndex.py +0 -0
  146. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensorIndexCOO.py +0 -0
  147. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensorIndexCSF.py +0 -0
  148. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Struct_.py +0 -0
  149. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Tensor.py +0 -0
  150. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/TensorDim.py +0 -0
  151. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Time.py +0 -0
  152. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/TimeUnit.py +0 -0
  153. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Timestamp.py +0 -0
  154. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Type.py +0 -0
  155. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Union.py +0 -0
  156. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/UnionMode.py +0 -0
  157. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Utf8.py +0 -0
  158. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/__init__.py +0 -0
  159. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/AlterColumnRequest.py +0 -0
  160. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/AlterProjectionTableRequest.py +0 -0
  161. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/AlterSchemaRequest.py +0 -0
  162. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/AlterTableRequest.py +0 -0
  163. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/Column.py +0 -0
  164. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/ColumnType.py +0 -0
  165. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/CreateProjectionRequest.py +0 -0
  166. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/CreateSchemaRequest.py +0 -0
  167. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/GetProjectionTableStatsResponse.py +0 -0
  168. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/GetTableStatsResponse.py +0 -0
  169. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/ImportDataRequest.py +0 -0
  170. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/ListProjectionsResponse.py +0 -0
  171. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/ListSchemasResponse.py +0 -0
  172. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/ListTablesResponse.py +0 -0
  173. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/ObjectDetails.py +0 -0
  174. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/S3File.py +0 -0
  175. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/VipRange.py +0 -0
  176. {vastdb-0.1.4 → vastdb-0.1.6}/vast_flatbuf/tabular/__init__.py +0 -0
  177. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/__init__.py +0 -0
  178. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/bench/__init__.py +0 -0
  179. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/tests/__init__.py +0 -0
  180. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/tests/test_duckdb.py +0 -0
  181. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/tests/test_sanity.py +0 -0
  182. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/tests/test_util.py +0 -0
  183. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb/tests/util.py +0 -0
  184. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb.egg-info/SOURCES.txt +0 -0
  185. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb.egg-info/dependency_links.txt +0 -0
  186. {vastdb-0.1.4 → vastdb-0.1.6}/vastdb.egg-info/requires.txt +0 -0
  187. {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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vastdb
3
- Version: 0.1.4
3
+ Version: 0.1.6
4
4
  Summary: VAST Data SDK
5
5
  Home-page: https://github.com/vast-data/vastdb_sdk
6
6
  Author: VAST DATA
@@ -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=(table['c2'] > 2) & table['c3'].isnull())
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=table['c2'].between(0, 1) | (table['c2'] > 10))
85
+ predicate=(_.c2.between(0, 1) | (table['c2'] > 10))
84
86
 
85
87
  # SELECT * FROM t WHERE c3 LIKE '%substring%'
86
- table.select(predicate=table['c3'].contains('substring'))
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=(table['c2'] > 2))
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.4' + suffix,
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=open('requirements.txt').read().strip().split('\n'),
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 = pa.Table.from_batches(t.select(columns=['sid'], predicate=t['sid'] == 10033007, config=config))
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 create_schema(self, path: str, fail_if_exists=True) -> "Schema":
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
- if current := self.schema(path, fail_if_missing=False):
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, path: str, fail_if_missing=True) -> Optional["Schema"]:
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
- s = self.schemas(path)
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, name: Optional[str] = None) -> List["Schema"]:
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 s in b.schemas():
38
- for t in s.tables():
39
- t.drop()
40
- s.drop()
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
 
@@ -89,7 +89,11 @@ class InvalidArgument(Exception):
89
89
  pass
90
90
 
91
91
 
92
- class TooWideRow(InvalidArgument):
92
+ class TooLargeRequest(InvalidArgument):
93
+ pass
94
+
95
+
96
+ class TooWideRow(TooLargeRequest):
93
97
  pass
94
98
 
95
99
 
@@ -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
- column_offset = self.build_column(position=positions_map[field_name])
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 = {'tabular-txid': str(txid), 'tabular-api-version-id': str(version_id),
843
- 'tabular-client-name': 'tabular-api'}
844
- for tag in client_tags:
845
- common_headers['tabular-client-tags-%d' % client_tags.index(tag)] = tag
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
- flatbuf = b''.join(res.iter_content(chunk_size=128))
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
- out = b''.join(res.iter_content(chunk_size=128))
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
- flatbuf = b''.join(res.iter_content(chunk_size=128))
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
- flatbuf = b''.join(res.iter_content(chunk_size=128))
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
- flatbuf = b''.join(res.iter_content(chunk_size=128))
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
- flatbuf = b''.join(res.iter_content(chunk_size=128))
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
- if not count_only:
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
- 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)
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
- 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)
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',