pixeltable 0.3.1__tar.gz → 0.3.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.3.1 → pixeltable-0.3.3}/PKG-INFO +7 -8
- {pixeltable-0.3.1 → pixeltable-0.3.3}/README.md +5 -7
- pixeltable-0.3.3/pixeltable/__init__.py +78 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/__version__.py +2 -2
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/catalog/__init__.py +1 -1
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/catalog/catalog.py +50 -27
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/catalog/column.py +27 -11
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/catalog/dir.py +6 -4
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/catalog/globals.py +8 -1
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/catalog/insertable_table.py +25 -15
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/catalog/named_function.py +10 -6
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/catalog/path.py +3 -2
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/catalog/path_dict.py +8 -6
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/catalog/schema_object.py +2 -1
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/catalog/table.py +123 -103
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/catalog/table_version.py +292 -143
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/catalog/table_version_path.py +8 -5
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/catalog/view.py +68 -27
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/dataframe.py +102 -72
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/env.py +39 -23
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exec/__init__.py +2 -2
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exec/aggregation_node.py +10 -4
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exec/cache_prefetch_node.py +5 -3
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exec/component_iteration_node.py +9 -8
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exec/data_row_batch.py +21 -10
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exec/exec_context.py +10 -3
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exec/exec_node.py +23 -12
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exec/expr_eval/evaluators.py +18 -17
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exec/expr_eval/expr_eval_node.py +29 -16
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exec/expr_eval/globals.py +33 -11
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exec/expr_eval/row_buffer.py +5 -6
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exec/expr_eval/schedulers.py +170 -42
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exec/in_memory_data_node.py +8 -7
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exec/row_update_node.py +15 -5
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exec/sql_node.py +56 -27
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/__init__.py +2 -2
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/arithmetic_expr.py +57 -26
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/column_property_ref.py +2 -1
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/column_ref.py +20 -15
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/comparison.py +6 -2
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/compound_predicate.py +1 -3
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/expr.py +101 -72
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/expr_dict.py +2 -1
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/expr_set.py +3 -1
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/function_call.py +39 -41
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/globals.py +1 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/in_predicate.py +2 -2
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/inline_expr.py +20 -17
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/json_mapper.py +4 -2
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/json_path.py +12 -18
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/literal.py +5 -9
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/method_ref.py +1 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/row_builder.py +31 -16
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/rowid_ref.py +14 -5
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/similarity_expr.py +11 -6
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/sql_element_cache.py +1 -1
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/type_cast.py +24 -9
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/ext/__init__.py +1 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/ext/functions/__init__.py +1 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/ext/functions/whisperx.py +2 -2
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/ext/functions/yolox.py +11 -11
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/func/aggregate_function.py +17 -13
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/func/callable_function.py +6 -6
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/func/expr_template_function.py +15 -14
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/func/function.py +16 -16
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/func/function_registry.py +11 -8
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/func/globals.py +4 -2
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/func/query_template_function.py +12 -13
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/func/signature.py +18 -9
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/func/tools.py +10 -17
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/func/udf.py +106 -11
- pixeltable-0.3.3/pixeltable/functions/__init__.py +30 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/anthropic.py +21 -15
- pixeltable-0.3.3/pixeltable/functions/fireworks.py +132 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/gemini.py +13 -3
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/globals.py +18 -6
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/huggingface.py +20 -38
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/image.py +7 -3
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/json.py +1 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/llama_cpp.py +1 -4
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/mistralai.py +31 -20
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/ollama.py +4 -18
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/openai.py +214 -109
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/replicate.py +11 -10
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/string.py +70 -7
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/timestamp.py +21 -8
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/together.py +66 -52
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/video.py +1 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/vision.py +14 -11
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/whisper.py +2 -1
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/globals.py +61 -28
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/index/btree.py +5 -3
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/index/embedding_index.py +15 -14
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/io/__init__.py +1 -1
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/io/external_store.py +30 -25
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/io/fiftyone.py +6 -14
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/io/globals.py +33 -27
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/io/hf_datasets.py +3 -2
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/io/label_studio.py +80 -71
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/io/pandas.py +33 -9
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/io/parquet.py +10 -13
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/iterators/__init__.py +1 -0
- pixeltable-0.3.3/pixeltable/iterators/audio.py +205 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/iterators/document.py +19 -8
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/iterators/image.py +6 -24
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/iterators/string.py +3 -6
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/iterators/video.py +1 -7
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/metadata/__init__.py +9 -2
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/metadata/converters/convert_10.py +2 -2
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/metadata/converters/convert_15.py +1 -5
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/metadata/converters/convert_16.py +2 -4
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/metadata/converters/convert_17.py +2 -4
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/metadata/converters/convert_18.py +2 -4
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/metadata/converters/convert_19.py +2 -5
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/metadata/converters/convert_20.py +1 -4
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/metadata/converters/convert_21.py +4 -6
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/metadata/converters/convert_22.py +1 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/metadata/converters/convert_23.py +5 -5
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/metadata/converters/convert_24.py +12 -13
- pixeltable-0.3.3/pixeltable/metadata/converters/convert_26.py +23 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/metadata/converters/util.py +3 -4
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/metadata/notes.py +1 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/metadata/schema.py +13 -2
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/plan.py +173 -98
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/store.py +42 -26
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/type_system.py +130 -85
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/utils/arrow.py +1 -7
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/utils/coco.py +16 -17
- pixeltable-0.3.3/pixeltable/utils/console_output.py +44 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/utils/description_helper.py +7 -7
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/utils/documents.py +3 -1
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/utils/filecache.py +13 -8
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/utils/http_server.py +9 -8
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/utils/media_store.py +2 -1
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/utils/pytorch.py +11 -14
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/utils/s3.py +1 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/utils/sql.py +1 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/utils/transactional_directory.py +2 -2
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pyproject.toml +11 -2
- pixeltable-0.3.1/pixeltable/__init__.py +0 -25
- pixeltable-0.3.1/pixeltable/functions/__init__.py +0 -11
- pixeltable-0.3.1/pixeltable/functions/fireworks.py +0 -74
- {pixeltable-0.3.1 → pixeltable-0.3.3}/LICENSE +0 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exceptions.py +0 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exec/expr_eval/__init__.py +0 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/array_slice.py +1 -1
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/data_row.py +2 -2
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/is_null.py +0 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/object_ref.py +1 -1
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/exprs/variable.py +0 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/func/__init__.py +0 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/audio.py +0 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/math.py +0 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/functions/util.py +0 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/index/__init__.py +1 -1
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/index/base.py +0 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/iterators/base.py +0 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/metadata/converters/convert_12.py +0 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/metadata/converters/convert_13.py +0 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/metadata/converters/convert_14.py +0 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/metadata/converters/convert_25.py +0 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/py.typed +0 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/utils/__init__.py +0 -0
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/utils/code.py +1 -1
- {pixeltable-0.3.1 → pixeltable-0.3.3}/pixeltable/utils/formatter.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pixeltable
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: AI Data Infrastructure: Declarative, Multimodal, and Incremental
|
|
5
5
|
Home-page: https://pixeltable.com/
|
|
6
6
|
License: Apache-2.0
|
|
@@ -27,6 +27,7 @@ Requires-Dist: av (>=10.0.0)
|
|
|
27
27
|
Requires-Dist: beautifulsoup4 (>=4.0.0,<5.0.0)
|
|
28
28
|
Requires-Dist: cloudpickle (>=2.2.1,<3.0.0)
|
|
29
29
|
Requires-Dist: ftfy (>=6.2.0,<7.0.0)
|
|
30
|
+
Requires-Dist: httpcore (>=1.0.3)
|
|
30
31
|
Requires-Dist: httpx (>=0.27)
|
|
31
32
|
Requires-Dist: jinja2 (>=3.1.3,<4.0.0)
|
|
32
33
|
Requires-Dist: jmespath (>=1.0.1,<2.0.0)
|
|
@@ -59,7 +60,7 @@ Description-Content-Type: text/markdown
|
|
|
59
60
|
alt="Pixeltable" width="50%" />
|
|
60
61
|
<br></br>
|
|
61
62
|
|
|
62
|
-
<h2>AI
|
|
63
|
+
<h2>Build Multimodal AI Apps with Declarative Data Infrastructure</h2>
|
|
63
64
|
|
|
64
65
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
65
66
|

|
|
@@ -81,17 +82,15 @@ Description-Content-Type: text/markdown
|
|
|
81
82
|
[LLM](https://docs.pixeltable.com/docs/document-indexing-and-rag)
|
|
82
83
|
</div>
|
|
83
84
|
|
|
84
|
-
Pixeltable is a
|
|
85
|
-
It features built-in versioning, lineage tracking, and incremental updates, enabling users to **store**, **transform**,
|
|
86
|
-
**index**, and **iterate** on data for their ML workflows.
|
|
85
|
+
Pixeltable is a declarative data infrastructure for building multimodal AI applications, enabling incremental storage, transformation, indexing, and orchestration of your data.
|
|
87
86
|
|
|
88
|
-
|
|
87
|
+
Consider it your unified foundation for computer vision, LLMs, and multimodal AI development - where complex data operations become simple tables and computed columns, including but not limited to:
|
|
89
88
|
|
|
90
|
-
- **
|
|
89
|
+
- **Work with all your data**: Interact with
|
|
91
90
|
[video data](https://github.com/pixeltable/pixeltable?tab=readme-ov-file#import-media-data-into-pixeltable-videos-images-audio)
|
|
92
91
|
at the [frame level](https://github.com/pixeltable/pixeltable?tab=readme-ov-file#text-and-image-similarity-search-on-video-frames-with-embedding-indexes)
|
|
93
92
|
and documents at the [chunk level](https://github.com/pixeltable/pixeltable?tab=readme-ov-file#automate-data-operations-with-views-eg-split-documents-into-chunks)
|
|
94
|
-
- **Incremental updates
|
|
93
|
+
- **Incremental updates**: Maintain an
|
|
95
94
|
[embedding index](https://docs.pixeltable.com/docs/embedding-vector-indexes) colocated with your data
|
|
96
95
|
- **Lazy evaluation and cache management**: Eliminates the need for
|
|
97
96
|
[manual frame extraction](https://docs.pixeltable.com/docs/object-detection-in-videos)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
alt="Pixeltable" width="50%" />
|
|
4
4
|
<br></br>
|
|
5
5
|
|
|
6
|
-
<h2>AI
|
|
6
|
+
<h2>Build Multimodal AI Apps with Declarative Data Infrastructure</h2>
|
|
7
7
|
|
|
8
8
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
9
9
|

|
|
@@ -25,17 +25,15 @@
|
|
|
25
25
|
[LLM](https://docs.pixeltable.com/docs/document-indexing-and-rag)
|
|
26
26
|
</div>
|
|
27
27
|
|
|
28
|
-
Pixeltable is a
|
|
29
|
-
It features built-in versioning, lineage tracking, and incremental updates, enabling users to **store**, **transform**,
|
|
30
|
-
**index**, and **iterate** on data for their ML workflows.
|
|
28
|
+
Pixeltable is a declarative data infrastructure for building multimodal AI applications, enabling incremental storage, transformation, indexing, and orchestration of your data.
|
|
31
29
|
|
|
32
|
-
|
|
30
|
+
Consider it your unified foundation for computer vision, LLMs, and multimodal AI development - where complex data operations become simple tables and computed columns, including but not limited to:
|
|
33
31
|
|
|
34
|
-
- **
|
|
32
|
+
- **Work with all your data**: Interact with
|
|
35
33
|
[video data](https://github.com/pixeltable/pixeltable?tab=readme-ov-file#import-media-data-into-pixeltable-videos-images-audio)
|
|
36
34
|
at the [frame level](https://github.com/pixeltable/pixeltable?tab=readme-ov-file#text-and-image-similarity-search-on-video-frames-with-embedding-indexes)
|
|
37
35
|
and documents at the [chunk level](https://github.com/pixeltable/pixeltable?tab=readme-ov-file#automate-data-operations-with-views-eg-split-documents-into-chunks)
|
|
38
|
-
- **Incremental updates
|
|
36
|
+
- **Incremental updates**: Maintain an
|
|
39
37
|
[embedding index](https://docs.pixeltable.com/docs/embedding-vector-indexes) colocated with your data
|
|
40
38
|
- **Lazy evaluation and cache management**: Eliminates the need for
|
|
41
39
|
[manual frame extraction](https://docs.pixeltable.com/docs/object-detection-in-videos)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from .__version__ import __version__, __version_tuple__
|
|
2
|
+
from .catalog import Column, InsertableTable, Table, UpdateStatus, View
|
|
3
|
+
from .dataframe import DataFrame
|
|
4
|
+
from .exceptions import Error
|
|
5
|
+
from .exprs import RELATIVE_PATH_ROOT
|
|
6
|
+
from .func import Aggregator, Function, expr_udf, query, uda, udf
|
|
7
|
+
from .globals import (
|
|
8
|
+
array,
|
|
9
|
+
configure_logging,
|
|
10
|
+
create_dir,
|
|
11
|
+
create_snapshot,
|
|
12
|
+
create_table,
|
|
13
|
+
create_view,
|
|
14
|
+
drop_dir,
|
|
15
|
+
drop_table,
|
|
16
|
+
get_table,
|
|
17
|
+
init,
|
|
18
|
+
list_dirs,
|
|
19
|
+
list_functions,
|
|
20
|
+
list_tables,
|
|
21
|
+
move,
|
|
22
|
+
tool,
|
|
23
|
+
tools,
|
|
24
|
+
)
|
|
25
|
+
from .type_system import (
|
|
26
|
+
Array,
|
|
27
|
+
ArrayType,
|
|
28
|
+
Audio,
|
|
29
|
+
AudioType,
|
|
30
|
+
Bool,
|
|
31
|
+
BoolType,
|
|
32
|
+
ColumnType,
|
|
33
|
+
Document,
|
|
34
|
+
DocumentType,
|
|
35
|
+
Float,
|
|
36
|
+
FloatType,
|
|
37
|
+
Image,
|
|
38
|
+
ImageType,
|
|
39
|
+
Int,
|
|
40
|
+
IntType,
|
|
41
|
+
Json,
|
|
42
|
+
JsonType,
|
|
43
|
+
Required,
|
|
44
|
+
String,
|
|
45
|
+
StringType,
|
|
46
|
+
Timestamp,
|
|
47
|
+
TimestampType,
|
|
48
|
+
Video,
|
|
49
|
+
VideoType,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# This import must go last to avoid circular imports.
|
|
53
|
+
from . import ext, functions, io, iterators # isort: skip
|
|
54
|
+
|
|
55
|
+
# This is the safest / most maintainable way to construct __all__: start with the default and "blacklist"
|
|
56
|
+
# stuff that we don't want in there. (Using a "whitelist" is considerably harder to maintain.)
|
|
57
|
+
|
|
58
|
+
__default_dir = set(symbol for symbol in dir() if not symbol.startswith('_'))
|
|
59
|
+
__removed_symbols = {
|
|
60
|
+
'catalog',
|
|
61
|
+
'dataframe',
|
|
62
|
+
'env',
|
|
63
|
+
'exceptions',
|
|
64
|
+
'exec',
|
|
65
|
+
'exprs',
|
|
66
|
+
'func',
|
|
67
|
+
'globals',
|
|
68
|
+
'index',
|
|
69
|
+
'metadata',
|
|
70
|
+
'plan',
|
|
71
|
+
'type_system',
|
|
72
|
+
'utils',
|
|
73
|
+
}
|
|
74
|
+
__all__ = sorted(list(__default_dir - __removed_symbols))
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def __dir__():
|
|
78
|
+
return __all__
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
# These version placeholders will be replaced during build.
|
|
2
|
-
__version__ =
|
|
3
|
-
__version_tuple__ = (0, 3,
|
|
2
|
+
__version__ = '0.3.3'
|
|
3
|
+
__version_tuple__ = (0, 3, 3)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from .catalog import Catalog
|
|
2
2
|
from .column import Column
|
|
3
3
|
from .dir import Dir
|
|
4
|
-
from .globals import
|
|
4
|
+
from .globals import IfExistsParam, IfNotExistsParam, MediaValidation, UpdateStatus, is_valid_identifier, is_valid_path
|
|
5
5
|
from .insertable_table import InsertableTable
|
|
6
6
|
from .named_function import NamedFunction
|
|
7
7
|
from .path import Path
|
|
@@ -8,18 +8,22 @@ from uuid import UUID
|
|
|
8
8
|
import sqlalchemy as sql
|
|
9
9
|
import sqlalchemy.orm as orm
|
|
10
10
|
|
|
11
|
+
import pixeltable.metadata.schema as schema
|
|
12
|
+
|
|
13
|
+
from .path_dict import PathDict
|
|
14
|
+
from .table import Table
|
|
11
15
|
from .table_version import TableVersion
|
|
12
16
|
from .table_version_path import TableVersionPath
|
|
13
|
-
from .table import Table
|
|
14
|
-
from .path_dict import PathDict
|
|
15
17
|
|
|
16
|
-
import
|
|
17
|
-
import pixeltable.
|
|
18
|
+
# This import must go last to avoid circular imports.
|
|
19
|
+
import pixeltable.env as env # isort: skip
|
|
18
20
|
|
|
19
21
|
_logger = logging.getLogger('pixeltable')
|
|
20
22
|
|
|
23
|
+
|
|
21
24
|
class Catalog:
|
|
22
25
|
"""A repository of catalog objects"""
|
|
26
|
+
|
|
23
27
|
_instance: Optional[Catalog] = None
|
|
24
28
|
|
|
25
29
|
@classmethod
|
|
@@ -28,7 +32,7 @@ class Catalog:
|
|
|
28
32
|
cls._instance = cls()
|
|
29
33
|
with orm.Session(env.Env.get().engine, future=True) as session:
|
|
30
34
|
cls._instance._load_table_versions(session)
|
|
31
|
-
#cls._instance._load_functions(session)
|
|
35
|
+
# cls._instance._load_functions(session)
|
|
32
36
|
return cls._instance
|
|
33
37
|
|
|
34
38
|
@classmethod
|
|
@@ -62,17 +66,24 @@ class Catalog:
|
|
|
62
66
|
_logger.info(f'Initialized catalog')
|
|
63
67
|
|
|
64
68
|
def _load_snapshot_version(
|
|
65
|
-
|
|
69
|
+
self, tbl_id: UUID, version: int, base: Optional[TableVersion], session: orm.Session
|
|
66
70
|
) -> TableVersion:
|
|
67
|
-
q =
|
|
68
|
-
.
|
|
69
|
-
.
|
|
70
|
-
.join(schema.
|
|
71
|
-
.
|
|
72
|
-
.where(
|
|
73
|
-
.where(sql.text((
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
q = (
|
|
72
|
+
session.query(schema.Table, schema.TableSchemaVersion)
|
|
73
|
+
.select_from(schema.Table)
|
|
74
|
+
.join(schema.TableVersion)
|
|
75
|
+
.join(schema.TableSchemaVersion)
|
|
76
|
+
.where(schema.Table.id == tbl_id)
|
|
77
|
+
.where(sql.text(f"({schema.TableVersion.__table__}.md->>'version')::int = {version}"))
|
|
78
|
+
.where(
|
|
79
|
+
sql.text(
|
|
80
|
+
(
|
|
81
|
+
f"({schema.TableVersion.__table__}.md->>'schema_version')::int = "
|
|
82
|
+
f'{schema.TableSchemaVersion.__table__}.{schema.TableSchemaVersion.schema_version.name}'
|
|
83
|
+
)
|
|
84
|
+
)
|
|
85
|
+
)
|
|
86
|
+
)
|
|
76
87
|
tbl_record, schema_version_record = q.one()
|
|
77
88
|
tbl_md = schema.md_from_dict(schema.TableMd, tbl_record.md)
|
|
78
89
|
schema_version_md = schema.md_from_dict(schema.TableSchemaVersionMd, schema_version_record.md)
|
|
@@ -86,15 +97,22 @@ class Catalog:
|
|
|
86
97
|
|
|
87
98
|
# load tables/views;
|
|
88
99
|
# do this in ascending order of creation ts so that we can resolve base references in one pass
|
|
89
|
-
q =
|
|
90
|
-
.
|
|
91
|
-
.
|
|
92
|
-
.join(schema.
|
|
93
|
-
.
|
|
94
|
-
.where(sql.text((
|
|
95
|
-
|
|
96
|
-
|
|
100
|
+
q = (
|
|
101
|
+
session.query(schema.Table, schema.TableSchemaVersion)
|
|
102
|
+
.select_from(schema.Table)
|
|
103
|
+
.join(schema.TableVersion)
|
|
104
|
+
.join(schema.TableSchemaVersion)
|
|
105
|
+
.where(sql.text(f"({schema.TableVersion.__table__}.md->>'version')::int = 0"))
|
|
106
|
+
.where(
|
|
107
|
+
sql.text(
|
|
108
|
+
(
|
|
109
|
+
f"({schema.Table.__table__}.md->>'current_schema_version')::int = "
|
|
110
|
+
f'{schema.TableSchemaVersion.__table__}.{schema.TableSchemaVersion.schema_version.name}'
|
|
111
|
+
)
|
|
112
|
+
)
|
|
113
|
+
)
|
|
97
114
|
.order_by(sql.text(f"({schema.TableVersion.__table__}.md->>'created_at')::float"))
|
|
115
|
+
)
|
|
98
116
|
|
|
99
117
|
for tbl_record, schema_version_record in q.all():
|
|
100
118
|
tbl_md = schema.md_from_dict(schema.TableMd, tbl_record.md)
|
|
@@ -129,14 +147,19 @@ class Catalog:
|
|
|
129
147
|
view_path = base_path
|
|
130
148
|
else:
|
|
131
149
|
tbl_version = TableVersion(
|
|
132
|
-
tbl_record.id,
|
|
150
|
+
tbl_record.id,
|
|
151
|
+
tbl_md,
|
|
152
|
+
tbl_md.current_version,
|
|
153
|
+
schema_version_md,
|
|
154
|
+
is_snapshot=is_snapshot,
|
|
133
155
|
base=base_path.tbl_version if is_snapshot else None,
|
|
134
|
-
base_path=base_path if not is_snapshot else None
|
|
156
|
+
base_path=base_path if not is_snapshot else None,
|
|
157
|
+
)
|
|
135
158
|
view_path = TableVersionPath(tbl_version, base=base_path)
|
|
136
159
|
|
|
137
160
|
tbl: Table = View(
|
|
138
|
-
tbl_record.id, tbl_record.dir_id, tbl_md.name, view_path, base_tbl_id,
|
|
139
|
-
|
|
161
|
+
tbl_record.id, tbl_record.dir_id, tbl_md.name, view_path, base_tbl_id, snapshot_only=snapshot_only
|
|
162
|
+
)
|
|
140
163
|
self.tbl_dependents[base_tbl_id].append(tbl)
|
|
141
164
|
|
|
142
165
|
else:
|
|
@@ -8,7 +8,8 @@ import sqlalchemy as sql
|
|
|
8
8
|
import pixeltable.exceptions as excs
|
|
9
9
|
import pixeltable.type_system as ts
|
|
10
10
|
from pixeltable import exprs
|
|
11
|
-
|
|
11
|
+
|
|
12
|
+
from .globals import MediaValidation, is_valid_identifier
|
|
12
13
|
|
|
13
14
|
if TYPE_CHECKING:
|
|
14
15
|
from .table_version import TableVersion
|
|
@@ -22,6 +23,7 @@ class Column:
|
|
|
22
23
|
A Column contains all the metadata necessary for executing queries and updates against a particular version of a
|
|
23
24
|
table/view.
|
|
24
25
|
"""
|
|
26
|
+
|
|
25
27
|
name: str
|
|
26
28
|
id: Optional[int]
|
|
27
29
|
col_type: ts.ColumnType
|
|
@@ -41,12 +43,19 @@ class Column:
|
|
|
41
43
|
tbl: Optional[TableVersion]
|
|
42
44
|
|
|
43
45
|
def __init__(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
self,
|
|
47
|
+
name: Optional[str],
|
|
48
|
+
col_type: Optional[ts.ColumnType] = None,
|
|
49
|
+
computed_with: Optional[exprs.Expr] = None,
|
|
50
|
+
is_pk: bool = False,
|
|
51
|
+
stored: bool = True,
|
|
52
|
+
media_validation: Optional[MediaValidation] = None,
|
|
53
|
+
col_id: Optional[int] = None,
|
|
54
|
+
schema_version_add: Optional[int] = None,
|
|
55
|
+
schema_version_drop: Optional[int] = None,
|
|
56
|
+
sa_col_type: Optional[sql.sqltypes.TypeEngine] = None,
|
|
57
|
+
records_errors: Optional[bool] = None,
|
|
58
|
+
value_expr_dict: Optional[dict[str, Any]] = None,
|
|
50
59
|
):
|
|
51
60
|
"""Column constructor.
|
|
52
61
|
|
|
@@ -81,7 +90,8 @@ class Column:
|
|
|
81
90
|
if value_expr is None:
|
|
82
91
|
raise excs.Error(
|
|
83
92
|
f'Column {name}: computed_with needs to be a valid Pixeltable expression, '
|
|
84
|
-
f'but it is a {type(computed_with)}'
|
|
93
|
+
f'but it is a {type(computed_with)}'
|
|
94
|
+
)
|
|
85
95
|
else:
|
|
86
96
|
self._value_expr = value_expr.copy()
|
|
87
97
|
self.col_type = self._value_expr.col_type
|
|
@@ -117,6 +127,7 @@ class Column:
|
|
|
117
127
|
# catalog has been fully loaded; that way, we encounter bugs in the serialization/deserialization logic earlier
|
|
118
128
|
if self.value_expr_dict is not None and self._value_expr is None:
|
|
119
129
|
from pixeltable import exprs
|
|
130
|
+
|
|
120
131
|
self._value_expr = exprs.Expr.from_dict(self.value_expr_dict)
|
|
121
132
|
return self._value_expr
|
|
122
133
|
|
|
@@ -129,12 +140,14 @@ class Column:
|
|
|
129
140
|
if self.stored == False and self.is_computed and self.has_window_fn_call():
|
|
130
141
|
raise excs.Error(
|
|
131
142
|
f'Column {self.name}: stored={self.stored} not supported for columns computed with window functions:'
|
|
132
|
-
f'\n{self.value_expr}'
|
|
143
|
+
f'\n{self.value_expr}'
|
|
144
|
+
)
|
|
133
145
|
|
|
134
146
|
def has_window_fn_call(self) -> bool:
|
|
135
147
|
if self.value_expr is None:
|
|
136
148
|
return False
|
|
137
149
|
from pixeltable import exprs
|
|
150
|
+
|
|
138
151
|
l = list(self.value_expr.subexprs(filter=lambda e: isinstance(e, exprs.FunctionCall) and e.is_window_fn_call))
|
|
139
152
|
return len(l) > 0
|
|
140
153
|
|
|
@@ -177,6 +190,7 @@ class Column:
|
|
|
177
190
|
If this is a computed col and the top-level expr is a function call, print the source, if possible.
|
|
178
191
|
"""
|
|
179
192
|
from pixeltable import exprs
|
|
193
|
+
|
|
180
194
|
if self.value_expr is None or not isinstance(self.value_expr, exprs.FunctionCall):
|
|
181
195
|
return
|
|
182
196
|
self.value_expr.fn.source()
|
|
@@ -188,8 +202,10 @@ class Column:
|
|
|
188
202
|
assert self.is_stored
|
|
189
203
|
# all storage columns are nullable (we deal with null errors in Pixeltable directly)
|
|
190
204
|
self.sa_col = sql.Column(
|
|
191
|
-
self.store_name(),
|
|
192
|
-
|
|
205
|
+
self.store_name(),
|
|
206
|
+
self.col_type.to_sa_type() if self.sa_col_type is None else self.sa_col_type,
|
|
207
|
+
nullable=True,
|
|
208
|
+
)
|
|
193
209
|
if self.is_computed or self.col_type.is_media_type():
|
|
194
210
|
self.sa_errormsg_col = sql.Column(self.errormsg_store_name(), ts.StringType().to_sa_type(), nullable=True)
|
|
195
211
|
self.sa_errortype_col = sql.Column(self.errortype_store_name(), ts.StringType().to_sa_type(), nullable=True)
|
|
@@ -6,13 +6,14 @@ from uuid import UUID
|
|
|
6
6
|
|
|
7
7
|
import sqlalchemy as sql
|
|
8
8
|
|
|
9
|
-
from .schema_object import SchemaObject
|
|
10
9
|
from pixeltable.env import Env
|
|
11
10
|
from pixeltable.metadata import schema
|
|
12
11
|
|
|
12
|
+
from .schema_object import SchemaObject
|
|
13
13
|
|
|
14
14
|
_logger = logging.getLogger('pixeltable')
|
|
15
15
|
|
|
16
|
+
|
|
16
17
|
class Dir(SchemaObject):
|
|
17
18
|
def __init__(self, id: UUID, parent_id: UUID, name: str):
|
|
18
19
|
super().__init__(id, name, parent_id)
|
|
@@ -23,8 +24,9 @@ class Dir(SchemaObject):
|
|
|
23
24
|
|
|
24
25
|
@property
|
|
25
26
|
def _has_dependents(self) -> bool:
|
|
26
|
-
"""
|
|
27
|
+
"""Returns True if this directory has any children."""
|
|
27
28
|
from pixeltable.catalog import Catalog, Path
|
|
29
|
+
|
|
28
30
|
return len(Catalog.get().paths.get_children(Path(self._path), child_type=None, recursive=False)) > 0
|
|
29
31
|
|
|
30
32
|
def _move(self, new_name: str, new_dir_id: UUID) -> None:
|
|
@@ -34,5 +36,5 @@ class Dir(SchemaObject):
|
|
|
34
36
|
conn.execute(
|
|
35
37
|
sql.update(schema.Dir.__table__)
|
|
36
38
|
.values({schema.Dir.parent_id: self._dir_id, schema.Dir.md: dataclasses.asdict(dir_md)})
|
|
37
|
-
.where(schema.Dir.id == self._id)
|
|
38
|
-
|
|
39
|
+
.where(schema.Dir.id == self._id)
|
|
40
|
+
)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
+
|
|
2
3
|
import dataclasses
|
|
3
4
|
import enum
|
|
4
5
|
import itertools
|
|
@@ -23,6 +24,7 @@ class UpdateStatus:
|
|
|
23
24
|
"""
|
|
24
25
|
Information about updates that resulted from a table operation.
|
|
25
26
|
"""
|
|
27
|
+
|
|
26
28
|
num_rows: int = 0
|
|
27
29
|
# TODO: disambiguate what this means: # of slots computed or # of columns computed?
|
|
28
30
|
num_computed_values: int = 0
|
|
@@ -51,6 +53,7 @@ class MediaValidation(enum.Enum):
|
|
|
51
53
|
val_strs = ', '.join(f'{s.lower()!r}' for s in cls.__members__.keys())
|
|
52
54
|
raise excs.Error(f'{error_prefix} must be one of: [{val_strs}]')
|
|
53
55
|
|
|
56
|
+
|
|
54
57
|
class IfExistsParam(enum.Enum):
|
|
55
58
|
ERROR = 0
|
|
56
59
|
IGNORE = 1
|
|
@@ -65,6 +68,7 @@ class IfExistsParam(enum.Enum):
|
|
|
65
68
|
val_strs = ', '.join(f'{s.lower()!r}' for s in cls.__members__.keys())
|
|
66
69
|
raise excs.Error(f'{param_name} must be one of: [{val_strs}]')
|
|
67
70
|
|
|
71
|
+
|
|
68
72
|
class IfNotExistsParam(enum.Enum):
|
|
69
73
|
ERROR = 0
|
|
70
74
|
IGNORE = 1
|
|
@@ -77,10 +81,12 @@ class IfNotExistsParam(enum.Enum):
|
|
|
77
81
|
val_strs = ', '.join(f'{s.lower()!r}' for s in cls.__members__.keys())
|
|
78
82
|
raise excs.Error(f'{param_name} must be one of: [{val_strs}]')
|
|
79
83
|
|
|
84
|
+
|
|
80
85
|
def is_valid_identifier(name: str) -> bool:
|
|
81
86
|
return name.isidentifier() and not name.startswith('_')
|
|
82
87
|
|
|
83
|
-
|
|
88
|
+
|
|
89
|
+
def is_valid_path(path: str, empty_is_valid: bool) -> bool:
|
|
84
90
|
if path == '':
|
|
85
91
|
return empty_is_valid
|
|
86
92
|
|
|
@@ -89,6 +95,7 @@ def is_valid_path(path: str, empty_is_valid : bool) -> bool:
|
|
|
89
95
|
return False
|
|
90
96
|
return True
|
|
91
97
|
|
|
98
|
+
|
|
92
99
|
def is_system_column_name(name: str) -> bool:
|
|
93
100
|
from pixeltable.catalog import InsertableTable, View
|
|
94
101
|
|
|
@@ -35,8 +35,15 @@ class InsertableTable(Table):
|
|
|
35
35
|
# MODULE-LOCAL, NOT PUBLIC
|
|
36
36
|
@classmethod
|
|
37
37
|
def _create(
|
|
38
|
-
cls,
|
|
39
|
-
|
|
38
|
+
cls,
|
|
39
|
+
dir_id: UUID,
|
|
40
|
+
name: str,
|
|
41
|
+
schema: dict[str, ts.ColumnType],
|
|
42
|
+
df: Optional[pxt.DataFrame],
|
|
43
|
+
primary_key: list[str],
|
|
44
|
+
num_retained_versions: int,
|
|
45
|
+
comment: str,
|
|
46
|
+
media_validation: MediaValidation,
|
|
40
47
|
) -> InsertableTable:
|
|
41
48
|
columns = cls._create_columns(schema)
|
|
42
49
|
cls._verify_schema(columns)
|
|
@@ -51,8 +58,14 @@ class InsertableTable(Table):
|
|
|
51
58
|
|
|
52
59
|
with orm.Session(Env.get().engine, future=True) as session:
|
|
53
60
|
_, tbl_version = TableVersion.create(
|
|
54
|
-
session,
|
|
55
|
-
|
|
61
|
+
session,
|
|
62
|
+
dir_id,
|
|
63
|
+
name,
|
|
64
|
+
columns,
|
|
65
|
+
num_retained_versions=num_retained_versions,
|
|
66
|
+
comment=comment,
|
|
67
|
+
media_validation=media_validation,
|
|
68
|
+
)
|
|
56
69
|
tbl = cls(dir_id, tbl_version)
|
|
57
70
|
# TODO We need to commit before doing the insertion, in order to avoid a primary key (version) collision
|
|
58
71
|
# when the table metadata gets updated. Once we have a notion of user-defined transactions in
|
|
@@ -68,7 +81,7 @@ class InsertableTable(Table):
|
|
|
68
81
|
cat.tbls[tbl._id] = tbl
|
|
69
82
|
|
|
70
83
|
_logger.info(f'Created table `{name}`, id={tbl_version.id}')
|
|
71
|
-
|
|
84
|
+
Env.get().console_logger.info(f'Created table `{name}`.')
|
|
72
85
|
return tbl
|
|
73
86
|
|
|
74
87
|
def get_metadata(self) -> dict[str, Any]:
|
|
@@ -84,16 +97,12 @@ class InsertableTable(Table):
|
|
|
84
97
|
/,
|
|
85
98
|
*,
|
|
86
99
|
print_stats: bool = False,
|
|
87
|
-
on_error: Literal['abort', 'ignore'] = 'abort'
|
|
100
|
+
on_error: Literal['abort', 'ignore'] = 'abort',
|
|
88
101
|
) -> UpdateStatus: ...
|
|
89
102
|
|
|
90
103
|
@overload
|
|
91
104
|
def insert(
|
|
92
|
-
self,
|
|
93
|
-
*,
|
|
94
|
-
print_stats: bool = False,
|
|
95
|
-
on_error: Literal['abort', 'ignore'] = 'abort',
|
|
96
|
-
**kwargs: Any
|
|
105
|
+
self, *, print_stats: bool = False, on_error: Literal['abort', 'ignore'] = 'abort', **kwargs: Any
|
|
97
106
|
) -> UpdateStatus: ...
|
|
98
107
|
|
|
99
108
|
def insert( # type: ignore[misc]
|
|
@@ -103,7 +112,7 @@ class InsertableTable(Table):
|
|
|
103
112
|
*,
|
|
104
113
|
print_stats: bool = False,
|
|
105
114
|
on_error: Literal['abort', 'ignore'] = 'abort',
|
|
106
|
-
**kwargs: Any
|
|
115
|
+
**kwargs: Any,
|
|
107
116
|
) -> UpdateStatus:
|
|
108
117
|
if rows is None:
|
|
109
118
|
rows = [kwargs]
|
|
@@ -127,14 +136,15 @@ class InsertableTable(Table):
|
|
|
127
136
|
if status.num_excs == 0:
|
|
128
137
|
cols_with_excs_str = ''
|
|
129
138
|
else:
|
|
130
|
-
cols_with_excs_str =
|
|
139
|
+
cols_with_excs_str = (
|
|
131
140
|
f' across {len(status.cols_with_excs)} column{"" if len(status.cols_with_excs) == 1 else "s"}'
|
|
141
|
+
)
|
|
132
142
|
cols_with_excs_str += f' ({", ".join(status.cols_with_excs)})'
|
|
133
143
|
msg = (
|
|
134
144
|
f'Inserted {status.num_rows} row{"" if status.num_rows == 1 else "s"} '
|
|
135
145
|
f'with {status.num_excs} error{"" if status.num_excs == 1 else "s"}{cols_with_excs_str}.'
|
|
136
146
|
)
|
|
137
|
-
|
|
147
|
+
Env.get().console_logger.info(msg)
|
|
138
148
|
_logger.info(f'InsertableTable {self._name}: {msg}')
|
|
139
149
|
FileCache.get().emit_eviction_warnings()
|
|
140
150
|
return status
|
|
@@ -164,7 +174,7 @@ class InsertableTable(Table):
|
|
|
164
174
|
row[col_name] = checked_val
|
|
165
175
|
except TypeError as e:
|
|
166
176
|
msg = str(e)
|
|
167
|
-
raise excs.Error(f'Error in column {col.name}: {msg[0].lower() + msg[1:]}\nRow: {row}')
|
|
177
|
+
raise excs.Error(f'Error in column {col.name}: {msg[0].lower() + msg[1:]}\nRow: {row}') from e
|
|
168
178
|
|
|
169
179
|
def delete(self, where: Optional['pxt.exprs.Expr'] = None) -> UpdateStatus:
|
|
170
180
|
"""Delete rows in this table.
|
|
@@ -6,18 +6,20 @@ from uuid import UUID
|
|
|
6
6
|
|
|
7
7
|
import sqlalchemy as sql
|
|
8
8
|
|
|
9
|
-
from .schema_object import SchemaObject
|
|
10
9
|
from pixeltable.env import Env
|
|
11
10
|
from pixeltable.metadata import schema
|
|
12
11
|
|
|
12
|
+
from .schema_object import SchemaObject
|
|
13
13
|
|
|
14
14
|
_logger = logging.getLogger('pixeltable')
|
|
15
15
|
|
|
16
|
+
|
|
16
17
|
class NamedFunction(SchemaObject):
|
|
17
18
|
"""
|
|
18
19
|
Contains references to functions that are named and have a path.
|
|
19
20
|
The Function itself is stored in the FunctionRegistry.
|
|
20
21
|
"""
|
|
22
|
+
|
|
21
23
|
def __init__(self, id: UUID, dir_id: UUID, name: str):
|
|
22
24
|
super().__init__(id, name, dir_id)
|
|
23
25
|
|
|
@@ -32,9 +34,11 @@ class NamedFunction(SchemaObject):
|
|
|
32
34
|
def _move(self, new_name: str, new_dir_id: UUID) -> None:
|
|
33
35
|
super()._move(new_name, new_dir_id)
|
|
34
36
|
with Env.get().engine.begin() as conn:
|
|
35
|
-
stmt = sql.text(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
stmt = sql.text(
|
|
38
|
+
(
|
|
39
|
+
f'UPDATE {schema.Function.__table__} '
|
|
40
|
+
f"SET {schema.Function.dir_id.name} = :new_dir_id, {schema.Function.md.name}['name'] = :new_name "
|
|
41
|
+
f'WHERE {schema.Function.id.name} = :id'
|
|
42
|
+
)
|
|
43
|
+
)
|
|
39
44
|
conn.execute(stmt, {'new_dir_id': new_dir_id, 'new_name': json.dumps(new_name), 'id': self._id})
|
|
40
|
-
|
|
@@ -3,10 +3,12 @@ from __future__ import annotations
|
|
|
3
3
|
import logging
|
|
4
4
|
|
|
5
5
|
from pixeltable import exceptions as excs
|
|
6
|
+
|
|
6
7
|
from .globals import is_valid_path
|
|
7
8
|
|
|
8
9
|
_logger = logging.getLogger('pixeltable')
|
|
9
10
|
|
|
11
|
+
|
|
10
12
|
class Path:
|
|
11
13
|
def __init__(self, path: str, empty_is_valid: bool = False):
|
|
12
14
|
if not is_valid_path(path, empty_is_valid):
|
|
@@ -50,9 +52,8 @@ class Path:
|
|
|
50
52
|
return False
|
|
51
53
|
if self.is_root and (other.len == 1 or not is_parent):
|
|
52
54
|
return True
|
|
53
|
-
is_prefix = self.components == other.components[:self.len]
|
|
55
|
+
is_prefix = self.components == other.components[: self.len]
|
|
54
56
|
return is_prefix and (self.len == (other.len - 1) or not is_parent)
|
|
55
57
|
|
|
56
58
|
def __str__(self) -> str:
|
|
57
59
|
return '.'.join(self.components)
|
|
58
|
-
|