pixeltable 0.4.2__tar.gz → 0.4.3__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.
Potentially problematic release.
This version of pixeltable might be problematic. Click here for more details.
- {pixeltable-0.4.2 → pixeltable-0.4.3}/PKG-INFO +1 -1
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/__init__.py +1 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/__version__.py +2 -2
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/__init__.py +2 -10
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/catalog.py +64 -38
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/column.py +22 -23
- pixeltable-0.4.3/pixeltable/catalog/globals.py +88 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/insertable_table.py +6 -4
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/path.py +6 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/table.py +51 -32
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/table_version.py +69 -45
- pixeltable-0.4.2/pixeltable/catalog/globals.py → pixeltable-0.4.3/pixeltable/catalog/update_status.py +40 -95
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/view.py +9 -2
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/config.py +76 -12
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/dataframe.py +1 -1
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/env.py +29 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/exec_node.py +7 -24
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/expr_eval/schedulers.py +134 -7
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/column_property_ref.py +21 -9
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/column_ref.py +5 -1
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/function_call.py +2 -2
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/row_builder.py +10 -9
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/rowid_ref.py +0 -4
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/function.py +3 -3
- pixeltable-0.4.3/pixeltable/functions/audio.py +57 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/video.py +57 -10
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/globals.py +61 -1
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/__init__.py +1 -1
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/external_store.py +3 -55
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/globals.py +4 -4
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/hf_datasets.py +10 -2
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/label_studio.py +16 -16
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/__init__.py +1 -1
- pixeltable-0.4.3/pixeltable/metadata/converters/convert_39.py +125 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/util.py +3 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/notes.py +1 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/schema.py +14 -2
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/plan.py +4 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/share/packager.py +20 -38
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/store.py +18 -50
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/type_system.py +2 -2
- pixeltable-0.4.3/pixeltable/utils/coroutine.py +24 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/media_store.py +39 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pyproject.toml +1 -1
- pixeltable-0.4.2/pixeltable/functions/audio.py +0 -30
- pixeltable-0.4.2/pixeltable/utils/coroutine.py +0 -41
- {pixeltable-0.4.2 → pixeltable-0.4.3}/LICENSE +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/README.md +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/dir.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/named_function.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/schema_object.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/table_version_handle.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/catalog/table_version_path.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exceptions.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/__init__.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/aggregation_node.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/cache_prefetch_node.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/component_iteration_node.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/data_row_batch.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/exec_context.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/expr_eval/__init__.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/expr_eval/evaluators.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/expr_eval/expr_eval_node.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/expr_eval/globals.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/expr_eval/row_buffer.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/in_memory_data_node.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/row_update_node.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exec/sql_node.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/__init__.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/arithmetic_expr.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/array_slice.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/comparison.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/compound_predicate.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/data_row.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/expr.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/expr_dict.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/expr_set.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/globals.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/in_predicate.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/inline_expr.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/is_null.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/json_mapper.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/json_path.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/literal.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/method_ref.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/object_ref.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/similarity_expr.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/sql_element_cache.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/string_op.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/type_cast.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/exprs/variable.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/ext/__init__.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/ext/functions/__init__.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/ext/functions/whisperx.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/ext/functions/yolox.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/__init__.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/aggregate_function.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/callable_function.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/expr_template_function.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/function_registry.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/globals.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/mcp.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/query_template_function.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/signature.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/tools.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/func/udf.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/__init__.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/anthropic.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/bedrock.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/date.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/deepseek.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/fireworks.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/gemini.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/globals.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/groq.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/huggingface.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/image.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/json.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/llama_cpp.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/math.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/mistralai.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/ollama.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/openai.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/replicate.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/string.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/timestamp.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/together.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/util.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/vision.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/functions/whisper.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/index/__init__.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/index/base.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/index/btree.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/index/embedding_index.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/datarows.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/fiftyone.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/pandas.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/parquet.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/table_data_conduit.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/io/utils.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/iterators/__init__.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/iterators/audio.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/iterators/base.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/iterators/document.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/iterators/image.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/iterators/string.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/iterators/video.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_10.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_12.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_13.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_14.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_15.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_16.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_17.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_18.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_19.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_20.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_21.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_22.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_23.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_24.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_25.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_26.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_27.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_28.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_29.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_30.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_31.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_32.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_33.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_34.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_35.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_36.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_37.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/converters/convert_38.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/metadata/utils.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/py.typed +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/share/__init__.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/share/publish.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/__init__.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/arrow.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/coco.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/code.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/console_output.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/dbms.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/description_helper.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/documents.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/exception_handler.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/filecache.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/formatter.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/http_server.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/iceberg.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/pytorch.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/s3.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/sql.py +0 -0
- {pixeltable-0.4.2 → pixeltable-0.4.3}/pixeltable/utils/transactional_directory.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pixeltable
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.3
|
|
4
4
|
Summary: AI Data Infrastructure: Declarative, Multimodal, and Incremental
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
Keywords: data-science,machine-learning,database,ai,computer-vision,chatbot,ml,artificial-intelligence,feature-engineering,multimodal,mlops,feature-store,vector-database,llm,genai
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
# These version placeholders will be replaced during build.
|
|
2
|
-
__version__ = '0.4.
|
|
3
|
-
__version_tuple__ = (0, 4,
|
|
2
|
+
__version__ = '0.4.3'
|
|
3
|
+
__version_tuple__ = (0, 4, 3)
|
|
@@ -3,16 +3,7 @@
|
|
|
3
3
|
from .catalog import Catalog
|
|
4
4
|
from .column import Column
|
|
5
5
|
from .dir import Dir
|
|
6
|
-
from .globals import
|
|
7
|
-
IfExistsParam,
|
|
8
|
-
IfNotExistsParam,
|
|
9
|
-
MediaValidation,
|
|
10
|
-
QColumnId,
|
|
11
|
-
RowCountStats,
|
|
12
|
-
UpdateStatus,
|
|
13
|
-
is_valid_identifier,
|
|
14
|
-
is_valid_path,
|
|
15
|
-
)
|
|
6
|
+
from .globals import IfExistsParam, IfNotExistsParam, MediaValidation, QColumnId, is_valid_identifier, is_valid_path
|
|
16
7
|
from .insertable_table import InsertableTable
|
|
17
8
|
from .named_function import NamedFunction
|
|
18
9
|
from .path import Path
|
|
@@ -21,4 +12,5 @@ from .table import Table
|
|
|
21
12
|
from .table_version import TableVersion
|
|
22
13
|
from .table_version_handle import ColumnHandle, TableVersionHandle
|
|
23
14
|
from .table_version_path import TableVersionPath
|
|
15
|
+
from .update_status import RowCountStats, UpdateStatus
|
|
24
16
|
from .view import View
|
|
@@ -766,56 +766,47 @@ class Catalog:
|
|
|
766
766
|
self._tbls[view._id] = view
|
|
767
767
|
return view
|
|
768
768
|
|
|
769
|
-
|
|
770
|
-
def create_replica(
|
|
771
|
-
self, path: Path, md: list[schema.FullTableMd], if_exists: IfExistsParam = IfExistsParam.ERROR
|
|
772
|
-
) -> None:
|
|
769
|
+
def create_replica(self, path: Path, md: list[schema.FullTableMd]) -> None:
|
|
773
770
|
"""
|
|
774
771
|
Creates table, table_version, and table_schema_version records for a replica with the given metadata.
|
|
775
772
|
The metadata should be presented in standard "ancestor order", with the table being replicated at
|
|
776
773
|
list position 0 and the (root) base table at list position -1.
|
|
777
|
-
|
|
778
|
-
TODO: create_replica() also needs to create the store tables and populate them in order to make
|
|
779
|
-
replica creation atomic.
|
|
780
774
|
"""
|
|
775
|
+
assert Env.get().in_xact
|
|
776
|
+
|
|
781
777
|
tbl_id = UUID(md[0].tbl_md.tbl_id)
|
|
782
778
|
|
|
783
|
-
|
|
784
|
-
existing
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
'but a different table already exists at that location.'
|
|
790
|
-
)
|
|
791
|
-
assert isinstance(existing, View)
|
|
792
|
-
return
|
|
779
|
+
existing = self._handle_path_collision(path, Table, False, if_exists=IfExistsParam.IGNORE) # type: ignore[type-abstract]
|
|
780
|
+
if existing is not None and existing._id != tbl_id:
|
|
781
|
+
raise excs.Error(
|
|
782
|
+
f'An attempt was made to create a replica table at {path!r}, '
|
|
783
|
+
'but a different table already exists at that location.'
|
|
784
|
+
)
|
|
793
785
|
|
|
794
786
|
# Ensure that the system directory exists.
|
|
795
787
|
self._create_dir(Path('_system', allow_system_paths=True), if_exists=IfExistsParam.IGNORE, parents=False)
|
|
796
788
|
|
|
797
|
-
# Now check to see if this table already exists in the catalog.
|
|
789
|
+
# Now check to see if this table UUID already exists in the catalog.
|
|
798
790
|
existing = Catalog.get().get_table_by_id(tbl_id)
|
|
799
791
|
if existing is not None:
|
|
800
792
|
existing_path = Path(existing._path(), allow_system_paths=True)
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
# into a named location), this will be a no-op, but it still serves to validate that the newly received
|
|
813
|
-
# metadata is identical to what's in the catalog.
|
|
814
|
-
self.__store_replica_md(path, md[0])
|
|
793
|
+
if existing_path != path:
|
|
794
|
+
# It does exist, under a different path from the specified one.
|
|
795
|
+
if not existing_path.is_system_path:
|
|
796
|
+
raise excs.Error(
|
|
797
|
+
f'That table has already been replicated as {existing_path!r}.\n'
|
|
798
|
+
f'Drop the existing replica if you wish to re-create it.'
|
|
799
|
+
)
|
|
800
|
+
# If it's a system table, then this means it was created at some point as the ancestor of some other
|
|
801
|
+
# table (a snapshot-over-snapshot scenario). In that case, we simply move it to the new (named)
|
|
802
|
+
# location.
|
|
803
|
+
self._move(existing_path, path)
|
|
815
804
|
|
|
816
|
-
# Now store the metadata for
|
|
805
|
+
# Now store the metadata for this replica's proper ancestors. If one or more proper ancestors
|
|
817
806
|
# do not yet exist in the store, they will be created as anonymous system tables.
|
|
818
|
-
|
|
807
|
+
# We instantiate the ancestors starting with the base table and ending with the immediate parent of the
|
|
808
|
+
# table being replicated.
|
|
809
|
+
for ancestor_md in md[:0:-1]:
|
|
819
810
|
ancestor_id = UUID(ancestor_md.tbl_md.tbl_id)
|
|
820
811
|
replica = Catalog.get().get_table_by_id(ancestor_id)
|
|
821
812
|
replica_path: Path
|
|
@@ -828,12 +819,22 @@ class Catalog:
|
|
|
828
819
|
# that was directly replicated by the user at some point). In either case, use the existing path.
|
|
829
820
|
replica_path = Path(replica._path(), allow_system_paths=True)
|
|
830
821
|
|
|
831
|
-
# Store the metadata; it could be a new version (in which case a new record will be created) or a
|
|
832
|
-
#
|
|
822
|
+
# Store the metadata; it could be a new version (in which case a new record will be created), or a known
|
|
823
|
+
# version (in which case the newly received metadata will be validated as identical).
|
|
824
|
+
# If it's a new version, this will result in a new TableVersion record being created.
|
|
833
825
|
self.__store_replica_md(replica_path, ancestor_md)
|
|
834
826
|
|
|
835
|
-
|
|
836
|
-
|
|
827
|
+
# Now we must clear cached metadata for the ancestor table, to force the next table operation to pick up
|
|
828
|
+
# the new TableVersion instance. This is necessary because computed columns of descendant tables might
|
|
829
|
+
# reference columns of the ancestor table that only exist in the new version.
|
|
830
|
+
replica = Catalog.get().get_table_by_id(ancestor_id)
|
|
831
|
+
assert replica is not None # If it didn't exist before, it must have been created by now.
|
|
832
|
+
replica._tbl_version_path.clear_cached_md()
|
|
833
|
+
|
|
834
|
+
# Finally, store the metadata for the table being replicated; as before, it could be a new version or a known
|
|
835
|
+
# version. If it's a new version, then a TableVersion record will be created, unless the table being replicated
|
|
836
|
+
# is a pure snapshot.
|
|
837
|
+
self.__store_replica_md(path, md[0])
|
|
837
838
|
|
|
838
839
|
def __store_replica_md(self, path: Path, md: schema.FullTableMd) -> None:
|
|
839
840
|
_logger.info(f'Creating replica table at {path!r} with ID: {md.tbl_md.tbl_id}')
|
|
@@ -917,10 +918,17 @@ class Catalog:
|
|
|
917
918
|
|
|
918
919
|
self.store_tbl_md(UUID(tbl_id), None, new_tbl_md, new_version_md, new_schema_version_md)
|
|
919
920
|
|
|
921
|
+
if new_version_md is not None and not md.is_pure_snapshot:
|
|
922
|
+
# It's a new version of a table that has a physical store, so we need to create a TableVersion instance.
|
|
923
|
+
TableVersion.create_replica(md)
|
|
924
|
+
|
|
920
925
|
@_retry_loop(for_write=False)
|
|
921
926
|
def get_table(self, path: Path) -> Table:
|
|
922
927
|
obj = Catalog.get()._get_schema_object(path, expected=Table, raise_if_not_exists=True)
|
|
923
928
|
assert isinstance(obj, Table)
|
|
929
|
+
# We need to clear cached metadata from tbl_version_path, in case the schema has been changed
|
|
930
|
+
# by another process.
|
|
931
|
+
obj._tbl_version_path.clear_cached_md()
|
|
924
932
|
return obj
|
|
925
933
|
|
|
926
934
|
@_retry_loop(for_write=True)
|
|
@@ -1398,6 +1406,24 @@ class Catalog:
|
|
|
1398
1406
|
session.add(schema_version_record)
|
|
1399
1407
|
session.flush() # Inform SQLAlchemy that we want to write these changes to the DB.
|
|
1400
1408
|
|
|
1409
|
+
def update_tbl_version_md(self, version_md: Optional[schema.TableVersionMd]) -> None:
|
|
1410
|
+
"""
|
|
1411
|
+
Update the TableVersion.md field in the DB. Typically used to update the cascade row count status.
|
|
1412
|
+
|
|
1413
|
+
Args:
|
|
1414
|
+
version_md: TableVersionMd
|
|
1415
|
+
"""
|
|
1416
|
+
assert self._in_write_xact
|
|
1417
|
+
session = Env.get().session
|
|
1418
|
+
|
|
1419
|
+
session.execute(
|
|
1420
|
+
sql.update(schema.TableVersion.__table__)
|
|
1421
|
+
.values({schema.TableVersion.md: dataclasses.asdict(version_md)})
|
|
1422
|
+
.where(schema.TableVersion.tbl_id == version_md.tbl_id, schema.TableVersion.version == version_md.version)
|
|
1423
|
+
)
|
|
1424
|
+
|
|
1425
|
+
session.flush() # Inform SQLAlchemy that we want to write these changes to the DB.
|
|
1426
|
+
|
|
1401
1427
|
def delete_tbl_md(self, tbl_id: UUID) -> None:
|
|
1402
1428
|
"""
|
|
1403
1429
|
Deletes all table metadata from the store for the given table UUID.
|
|
@@ -36,11 +36,10 @@ class Column:
|
|
|
36
36
|
_media_validation: Optional[MediaValidation] # if not set, TableVersion.media_validation applies
|
|
37
37
|
schema_version_add: Optional[int]
|
|
38
38
|
schema_version_drop: Optional[int]
|
|
39
|
-
|
|
39
|
+
_stores_cellmd: Optional[bool]
|
|
40
40
|
sa_col: Optional[sql.schema.Column]
|
|
41
41
|
sa_col_type: Optional[sql.sqltypes.TypeEngine]
|
|
42
|
-
|
|
43
|
-
sa_errortype_col: Optional[sql.schema.Column]
|
|
42
|
+
sa_cellmd_col: Optional[sql.schema.Column] # JSON metadata for the cell, e.g. errortype, errormsg for media columns
|
|
44
43
|
_value_expr: Optional[exprs.Expr]
|
|
45
44
|
value_expr_dict: Optional[dict[str, Any]]
|
|
46
45
|
# we store a TableVersion here, not a TableVersionHandle, because this column is owned by that TableVersion instance
|
|
@@ -59,7 +58,7 @@ class Column:
|
|
|
59
58
|
schema_version_add: Optional[int] = None,
|
|
60
59
|
schema_version_drop: Optional[int] = None,
|
|
61
60
|
sa_col_type: Optional[sql.sqltypes.TypeEngine] = None,
|
|
62
|
-
|
|
61
|
+
stores_cellmd: Optional[bool] = None,
|
|
63
62
|
value_expr_dict: Optional[dict[str, Any]] = None,
|
|
64
63
|
tbl: Optional[TableVersion] = None,
|
|
65
64
|
):
|
|
@@ -118,15 +117,14 @@ class Column:
|
|
|
118
117
|
self.schema_version_add = schema_version_add
|
|
119
118
|
self.schema_version_drop = schema_version_drop
|
|
120
119
|
|
|
121
|
-
self.
|
|
120
|
+
self._stores_cellmd = stores_cellmd
|
|
122
121
|
|
|
123
122
|
# column in the stored table for the values of this Column
|
|
124
123
|
self.sa_col = None
|
|
125
124
|
self.sa_col_type = sa_col_type
|
|
126
125
|
|
|
127
126
|
# computed cols also have storage columns for the exception string and type
|
|
128
|
-
self.
|
|
129
|
-
self.sa_errortype_col = None
|
|
127
|
+
self.sa_cellmd_col = None
|
|
130
128
|
|
|
131
129
|
def init_value_expr(self) -> None:
|
|
132
130
|
from pixeltable import exprs
|
|
@@ -203,11 +201,11 @@ class Column:
|
|
|
203
201
|
return self.stored
|
|
204
202
|
|
|
205
203
|
@property
|
|
206
|
-
def
|
|
204
|
+
def stores_cellmd(self) -> bool:
|
|
207
205
|
"""True if this column also stores error information."""
|
|
208
206
|
# default: record errors for computed and media columns
|
|
209
|
-
if self.
|
|
210
|
-
return self.
|
|
207
|
+
if self._stores_cellmd is not None:
|
|
208
|
+
return self._stores_cellmd
|
|
211
209
|
return self.is_stored and (self.is_computed or self.col_type.is_media_type())
|
|
212
210
|
|
|
213
211
|
@property
|
|
@@ -243,28 +241,29 @@ class Column:
|
|
|
243
241
|
"""
|
|
244
242
|
assert self.is_stored
|
|
245
243
|
# all storage columns are nullable (we deal with null errors in Pixeltable directly)
|
|
246
|
-
self.sa_col = sql.Column(
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
nullable=True
|
|
250
|
-
)
|
|
251
|
-
if self.is_computed or self.col_type.is_media_type():
|
|
252
|
-
self.sa_errormsg_col = sql.Column(self.errormsg_store_name(), ts.StringType().to_sa_type(), nullable=True)
|
|
253
|
-
self.sa_errortype_col = sql.Column(self.errortype_store_name(), ts.StringType().to_sa_type(), nullable=True)
|
|
244
|
+
self.sa_col = sql.Column(self.store_name(), self.get_sa_col_type(), nullable=True)
|
|
245
|
+
if self.stores_cellmd:
|
|
246
|
+
# JSON metadata for the cell, e.g. errortype, errormsg for media columns
|
|
247
|
+
self.sa_cellmd_col = sql.Column(self.cellmd_store_name(), self.sa_cellmd_type(), nullable=True)
|
|
254
248
|
|
|
255
249
|
def get_sa_col_type(self) -> sql.sqltypes.TypeEngine:
|
|
256
250
|
return self.col_type.to_sa_type() if self.sa_col_type is None else self.sa_col_type
|
|
257
251
|
|
|
252
|
+
@classmethod
|
|
253
|
+
def cellmd_type(cls) -> ts.ColumnType:
|
|
254
|
+
return ts.JsonType(nullable=True)
|
|
255
|
+
|
|
256
|
+
@classmethod
|
|
257
|
+
def sa_cellmd_type(cls) -> sql.sqltypes.TypeEngine:
|
|
258
|
+
return cls.cellmd_type().to_sa_type()
|
|
259
|
+
|
|
258
260
|
def store_name(self) -> str:
|
|
259
261
|
assert self.id is not None
|
|
260
262
|
assert self.is_stored
|
|
261
263
|
return f'col_{self.id}'
|
|
262
264
|
|
|
263
|
-
def
|
|
264
|
-
return f'{self.store_name()}
|
|
265
|
-
|
|
266
|
-
def errortype_store_name(self) -> str:
|
|
267
|
-
return f'{self.store_name()}_errortype'
|
|
265
|
+
def cellmd_store_name(self) -> str:
|
|
266
|
+
return f'{self.store_name()}_cellmd'
|
|
268
267
|
|
|
269
268
|
def __str__(self) -> str:
|
|
270
269
|
return f'{self.name}: {self.col_type}'
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import enum
|
|
4
|
+
import itertools
|
|
5
|
+
import logging
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from typing import Optional
|
|
8
|
+
from uuid import UUID
|
|
9
|
+
|
|
10
|
+
import pixeltable.exceptions as excs
|
|
11
|
+
|
|
12
|
+
_logger = logging.getLogger('pixeltable')
|
|
13
|
+
|
|
14
|
+
# name of the position column in a component view
|
|
15
|
+
_POS_COLUMN_NAME = 'pos'
|
|
16
|
+
_ROWID_COLUMN_NAME = '_rowid'
|
|
17
|
+
|
|
18
|
+
# Set of symbols that are predefined in the `InsertableTable` class (and are therefore not allowed as column names).
|
|
19
|
+
# This will be populated lazily to avoid circular imports.
|
|
20
|
+
_PREDEF_SYMBOLS: Optional[set[str]] = None
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass(frozen=True)
|
|
24
|
+
class QColumnId:
|
|
25
|
+
"""Qualified column id"""
|
|
26
|
+
|
|
27
|
+
tbl_id: UUID
|
|
28
|
+
col_id: int
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class MediaValidation(enum.Enum):
|
|
32
|
+
ON_READ = 0
|
|
33
|
+
ON_WRITE = 1
|
|
34
|
+
|
|
35
|
+
@classmethod
|
|
36
|
+
def validated(cls, name: str, error_prefix: str) -> MediaValidation:
|
|
37
|
+
try:
|
|
38
|
+
return cls[name.upper()]
|
|
39
|
+
except KeyError:
|
|
40
|
+
val_strs = ', '.join(f'{s.lower()!r}' for s in cls.__members__)
|
|
41
|
+
raise excs.Error(f'{error_prefix} must be one of: [{val_strs}]') from None
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class IfExistsParam(enum.Enum):
|
|
45
|
+
ERROR = 0
|
|
46
|
+
IGNORE = 1
|
|
47
|
+
REPLACE = 2
|
|
48
|
+
REPLACE_FORCE = 3
|
|
49
|
+
|
|
50
|
+
@classmethod
|
|
51
|
+
def validated(cls, param_val: str, param_name: str) -> IfExistsParam:
|
|
52
|
+
try:
|
|
53
|
+
return cls[param_val.upper()]
|
|
54
|
+
except KeyError:
|
|
55
|
+
val_strs = ', '.join(f'{s.lower()!r}' for s in cls.__members__)
|
|
56
|
+
raise excs.Error(f'{param_name} must be one of: [{val_strs}]') from None
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class IfNotExistsParam(enum.Enum):
|
|
60
|
+
ERROR = 0
|
|
61
|
+
IGNORE = 1
|
|
62
|
+
|
|
63
|
+
@classmethod
|
|
64
|
+
def validated(cls, param_val: str, param_name: str) -> IfNotExistsParam:
|
|
65
|
+
try:
|
|
66
|
+
return cls[param_val.upper()]
|
|
67
|
+
except KeyError:
|
|
68
|
+
val_strs = ', '.join(f'{s.lower()!r}' for s in cls.__members__)
|
|
69
|
+
raise excs.Error(f'{param_name} must be one of: [{val_strs}]') from None
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def is_valid_identifier(name: str, allow_system_identifiers: bool = False) -> bool:
|
|
73
|
+
return name.isidentifier() and (allow_system_identifiers or not name.startswith('_'))
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def is_valid_path(path: str, empty_is_valid: bool, allow_system_paths: bool = False) -> bool:
|
|
77
|
+
if path == '':
|
|
78
|
+
return empty_is_valid
|
|
79
|
+
return all(is_valid_identifier(part, allow_system_paths) for part in path.split('.'))
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def is_system_column_name(name: str) -> bool:
|
|
83
|
+
from pixeltable.catalog import InsertableTable, View
|
|
84
|
+
|
|
85
|
+
global _PREDEF_SYMBOLS # noqa: PLW0603
|
|
86
|
+
if _PREDEF_SYMBOLS is None:
|
|
87
|
+
_PREDEF_SYMBOLS = set(itertools.chain(dir(InsertableTable), dir(View)))
|
|
88
|
+
return name == _POS_COLUMN_NAME or name in _PREDEF_SYMBOLS
|
|
@@ -10,11 +10,12 @@ from pixeltable import exceptions as excs, type_system as ts
|
|
|
10
10
|
from pixeltable.env import Env
|
|
11
11
|
from pixeltable.utils.filecache import FileCache
|
|
12
12
|
|
|
13
|
-
from .globals import MediaValidation
|
|
13
|
+
from .globals import MediaValidation
|
|
14
14
|
from .table import Table
|
|
15
15
|
from .table_version import TableVersion
|
|
16
16
|
from .table_version_handle import TableVersionHandle
|
|
17
17
|
from .table_version_path import TableVersionPath
|
|
18
|
+
from .update_status import UpdateStatus
|
|
18
19
|
|
|
19
20
|
if TYPE_CHECKING:
|
|
20
21
|
from pixeltable import exprs
|
|
@@ -106,6 +107,7 @@ class InsertableTable(Table):
|
|
|
106
107
|
|
|
107
108
|
def _get_metadata(self) -> dict[str, Any]:
|
|
108
109
|
md = super()._get_metadata()
|
|
110
|
+
md['base'] = None
|
|
109
111
|
md['is_view'] = False
|
|
110
112
|
md['is_snapshot'] = False
|
|
111
113
|
return md
|
|
@@ -171,14 +173,14 @@ class InsertableTable(Table):
|
|
|
171
173
|
from pixeltable.catalog import Catalog
|
|
172
174
|
from pixeltable.io.table_data_conduit import DFTableDataConduit
|
|
173
175
|
|
|
174
|
-
status = pxt.UpdateStatus()
|
|
175
176
|
with Catalog.get().begin_xact(tbl=self._tbl_version_path, for_write=True, lock_mutable_tree=True):
|
|
176
177
|
if isinstance(data_source, DFTableDataConduit):
|
|
177
|
-
status =
|
|
178
|
+
status = pxt.UpdateStatus()
|
|
179
|
+
status += self._tbl_version.get().insert(
|
|
178
180
|
rows=None, df=data_source.pxt_df, print_stats=print_stats, fail_on_exception=fail_on_exception
|
|
179
181
|
)
|
|
180
182
|
else:
|
|
181
|
-
status = UpdateStatus()
|
|
183
|
+
status = pxt.UpdateStatus()
|
|
182
184
|
for row_batch in data_source.valid_row_batch():
|
|
183
185
|
status += self._tbl_version.get().insert(
|
|
184
186
|
rows=row_batch, df=None, print_stats=print_stats, fail_on_exception=fail_on_exception
|
|
@@ -77,5 +77,11 @@ class Path:
|
|
|
77
77
|
def __str__(self) -> str:
|
|
78
78
|
return '.'.join(self.components)
|
|
79
79
|
|
|
80
|
+
def __eq__(self, other: object) -> bool:
|
|
81
|
+
return isinstance(other, Path) and str(self) == str(other)
|
|
82
|
+
|
|
83
|
+
def __hash__(self) -> int:
|
|
84
|
+
return hash(str(self))
|
|
85
|
+
|
|
80
86
|
def __lt__(self, other: Path) -> bool:
|
|
81
87
|
return str(self) < str(other)
|