pixeltable 0.2.7__tar.gz → 0.2.8__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.2.7 → pixeltable-0.2.8}/PKG-INFO +2 -2
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/__version__.py +2 -2
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/column.py +0 -6
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/table.py +15 -42
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/table_version.py +15 -96
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/table_version_path.py +1 -6
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/datatransfer/label_studio.py +108 -182
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/datatransfer/remote.py +3 -31
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/env.py +4 -8
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/io/globals.py +2 -3
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/metadata/__init__.py +1 -1
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/metadata/schema.py +0 -3
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/tool/create_test_db_dump.py +3 -5
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pyproject.toml +2 -2
- pixeltable-0.2.7/pixeltable/metadata/converters/convert_15.py +0 -29
- pixeltable-0.2.7/pixeltable/metadata/converters/util.py +0 -63
- {pixeltable-0.2.7 → pixeltable-0.2.8}/LICENSE +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/README.md +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/__init__.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/__init__.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/catalog.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/dir.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/globals.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/insertable_table.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/named_function.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/path.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/path_dict.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/schema_object.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/view.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/dataframe.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/datatransfer/__init__.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exceptions.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/__init__.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/aggregation_node.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/cache_prefetch_node.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/component_iteration_node.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/data_row_batch.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/exec_context.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/exec_node.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/expr_eval_node.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/in_memory_data_node.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/media_validation_node.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/sql_scan_node.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/__init__.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/arithmetic_expr.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/array_slice.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/column_property_ref.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/column_ref.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/comparison.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/compound_predicate.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/data_row.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/expr.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/expr_set.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/function_call.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/globals.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/image_member_access.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/in_predicate.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/inline_array.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/inline_dict.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/is_null.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/json_mapper.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/json_path.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/literal.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/object_ref.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/predicate.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/row_builder.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/rowid_ref.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/similarity_expr.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/type_cast.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/variable.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/ext/__init__.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/ext/functions/whisperx.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/ext/functions/yolox.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/func/__init__.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/func/aggregate_function.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/func/callable_function.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/func/expr_template_function.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/func/function.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/func/function_registry.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/func/globals.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/func/signature.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/func/udf.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/__init__.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/eval.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/fireworks.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/huggingface.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/image.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/openai.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/pil/image.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/string.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/together.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/util.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/video.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/globals.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/index/__init__.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/index/base.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/index/btree.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/index/embedding_index.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/io/__init__.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/io/hf_datasets.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/io/pandas.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/io/parquet.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/iterators/__init__.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/iterators/base.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/iterators/document.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/iterators/video.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/metadata/converters/convert_10.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/metadata/converters/convert_12.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/metadata/converters/convert_13.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/metadata/converters/convert_14.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/plan.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/store.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/tool/create_test_video.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/type_system.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/__init__.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/arrow.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/coco.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/documents.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/filecache.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/help.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/http_server.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/media_store.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/pytorch.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/s3.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/sql.py +0 -0
- {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/transactional_directory.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pixeltable
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.8
|
|
4
4
|
Summary: Pixeltable: The Multimodal AI Data Plane
|
|
5
5
|
Author: Marcel Kornacker
|
|
6
6
|
Author-email: marcelk@gmail.com
|
|
@@ -21,7 +21,7 @@ Requires-Dist: more-itertools (>=10.2,<11.0)
|
|
|
21
21
|
Requires-Dist: numpy (>=1.25)
|
|
22
22
|
Requires-Dist: opencv-python-headless (>=4.7.0.68,<5.0.0.0)
|
|
23
23
|
Requires-Dist: pandas (>=2.0,<3.0)
|
|
24
|
-
Requires-Dist: pgserver (==0.1.
|
|
24
|
+
Requires-Dist: pgserver (==0.1.4)
|
|
25
25
|
Requires-Dist: pgvector (>=0.2.1,<0.3.0)
|
|
26
26
|
Requires-Dist: pillow (>=9.3.0)
|
|
27
27
|
Requires-Dist: psutil (>=5.9.5,<6.0.0)
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
# These version placeholders will be replaced during build.
|
|
2
|
-
__version__ = "0.2.
|
|
3
|
-
__version_tuple__ = (0, 2,
|
|
2
|
+
__version__ = "0.2.8"
|
|
3
|
+
__version_tuple__ = (0, 2, 8)
|
|
@@ -87,11 +87,6 @@ class Column:
|
|
|
87
87
|
self.schema_version_add = schema_version_add
|
|
88
88
|
self.schema_version_drop = schema_version_drop
|
|
89
89
|
|
|
90
|
-
# stored_proxy may be set later if this is a non-stored column.
|
|
91
|
-
# if col1.stored_proxy == col2, then also col1 == col2.proxy_base.
|
|
92
|
-
self.stored_proxy: Optional[Column] = None
|
|
93
|
-
self.proxy_base: Optional[Column] = None
|
|
94
|
-
|
|
95
90
|
self._records_errors = records_errors
|
|
96
91
|
|
|
97
92
|
# column in the stored table for the values of this Column
|
|
@@ -101,7 +96,6 @@ class Column:
|
|
|
101
96
|
# computed cols also have storage columns for the exception string and type
|
|
102
97
|
self.sa_errormsg_col: Optional[sql.schema.Column] = None
|
|
103
98
|
self.sa_errortype_col: Optional[sql.schema.Column] = None
|
|
104
|
-
|
|
105
99
|
from .table_version import TableVersion
|
|
106
100
|
self.tbl: Optional[TableVersion] = None # set by owning TableVersion
|
|
107
101
|
|
|
@@ -735,58 +735,31 @@ class Table(SchemaObject):
|
|
|
735
735
|
col_mapping: An optional mapping of columns from this `Table` to columns in the `Remote`.
|
|
736
736
|
"""
|
|
737
737
|
# TODO(aaron-siegel): Refactor `col_mapping`
|
|
738
|
+
if len(self._get_remotes()) > 0:
|
|
739
|
+
raise excs.Error('Linking more than one `Remote` to a table is not currently supported.')
|
|
738
740
|
self._check_is_dropped()
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
push_cols = remote.get_export_columns()
|
|
742
|
-
pull_cols = remote.get_import_columns()
|
|
741
|
+
export_cols = remote.get_export_columns()
|
|
742
|
+
import_cols = remote.get_import_columns()
|
|
743
743
|
is_col_mapping_user_specified = col_mapping is not None
|
|
744
744
|
if col_mapping is None:
|
|
745
745
|
# Use the identity mapping by default if `col_mapping` is not specified
|
|
746
|
-
col_mapping = {col: col for col in itertools.chain(
|
|
747
|
-
self._validate_remote(
|
|
748
|
-
_logger.info(f'Linking remote {remote} to table `{self.get_name()}`.')
|
|
746
|
+
col_mapping = {col: col for col in itertools.chain(export_cols.keys(), import_cols.keys())}
|
|
747
|
+
self._validate_remote(export_cols, import_cols, col_mapping, is_col_mapping_user_specified)
|
|
749
748
|
self.tbl_version_path.tbl_version.link(remote, col_mapping)
|
|
750
749
|
print(f'Linked remote {remote} to table `{self.get_name()}`.')
|
|
751
750
|
|
|
752
|
-
def unlink(
|
|
753
|
-
self,
|
|
754
|
-
remotes: Optional['pixeltable.datatransfer.Remote' | list['pixeltable.datatransfer.Remote']] = None,
|
|
755
|
-
*,
|
|
756
|
-
delete_remote_data: bool = False,
|
|
757
|
-
ignore_errors: bool = False
|
|
758
|
-
) -> None:
|
|
751
|
+
def unlink(self) -> None:
|
|
759
752
|
"""
|
|
760
753
|
Unlinks this table's `Remote`s.
|
|
761
|
-
|
|
762
|
-
Args:
|
|
763
|
-
remotes: If specified, will unlink only the specified `Remote` or list of `Remote`s. If not specified,
|
|
764
|
-
will unlink all of this table's `Remote`s.
|
|
765
|
-
ignore_errors (bool): If `True`, no exception will be thrown if the specified `Remote` is not linked
|
|
766
|
-
to this table.
|
|
767
|
-
delete_remote_data (bool): If `True`, then the remote data source will also be deleted. WARNING: This
|
|
768
|
-
is a destructive operation that will delete data outside Pixeltable, and cannot be undone.
|
|
769
|
-
|
|
770
754
|
"""
|
|
771
755
|
self._check_is_dropped()
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
if remotes is None:
|
|
775
|
-
remotes = list(all_remotes.keys())
|
|
776
|
-
elif isinstance(remotes, pixeltable.datatransfer.Remote):
|
|
777
|
-
remotes = [remotes]
|
|
778
|
-
|
|
779
|
-
# Validation
|
|
780
|
-
if not ignore_errors:
|
|
781
|
-
for remote in remotes:
|
|
782
|
-
if remote not in all_remotes:
|
|
783
|
-
raise excs.Error(f'Remote {remote} is not linked to table `{self.get_name()}`')
|
|
756
|
+
remotes = self._get_remotes()
|
|
757
|
+
assert len(remotes) <= 1
|
|
784
758
|
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
remote.delete()
|
|
759
|
+
remote = next(iter(remotes.keys()))
|
|
760
|
+
self.tbl_version_path.tbl_version.unlink(remote)
|
|
761
|
+
# TODO: Provide an option to auto-delete the project
|
|
762
|
+
print(f'Unlinked remote {remote} from table `{self.get_name()}`.')
|
|
790
763
|
|
|
791
764
|
def _validate_remote(
|
|
792
765
|
self,
|
|
@@ -823,7 +796,7 @@ class Table(SchemaObject):
|
|
|
823
796
|
r_col_type = export_cols[r_col]
|
|
824
797
|
if not r_col_type.is_supertype_of(t_col_type):
|
|
825
798
|
raise excs.Error(
|
|
826
|
-
f'Column `{t_col}` cannot be exported to remote column `{r_col}` (incompatible types
|
|
799
|
+
f'Column `{t_col}` cannot be exported to remote column `{r_col}` (incompatible types)'
|
|
827
800
|
)
|
|
828
801
|
if r_col in import_cols:
|
|
829
802
|
# Validate that the remote column can be assigned to the table column
|
|
@@ -834,7 +807,7 @@ class Table(SchemaObject):
|
|
|
834
807
|
r_col_type = import_cols[r_col]
|
|
835
808
|
if not t_col_type.is_supertype_of(r_col_type):
|
|
836
809
|
raise excs.Error(
|
|
837
|
-
f'Column `{t_col}` cannot be imported from remote column `{r_col}` (incompatible types
|
|
810
|
+
f'Column `{t_col}` cannot be imported from remote column `{r_col}` (incompatible types)'
|
|
838
811
|
)
|
|
839
812
|
|
|
840
813
|
def _get_remotes(self) -> dict[pixeltable.datatransfer.Remote, dict[str, str]]:
|
|
@@ -24,7 +24,6 @@ from pixeltable.utils.filecache import FileCache
|
|
|
24
24
|
from pixeltable.utils.media_store import MediaStore
|
|
25
25
|
from .column import Column
|
|
26
26
|
from .globals import UpdateStatus, POS_COLUMN_NAME, is_valid_identifier
|
|
27
|
-
from ..func.globals import resolve_symbol
|
|
28
27
|
|
|
29
28
|
_logger = logging.getLogger('pixeltable')
|
|
30
29
|
|
|
@@ -121,7 +120,7 @@ class TableVersion:
|
|
|
121
120
|
# init schema after we determined whether we're a component view, and before we create the store table
|
|
122
121
|
self.cols: list[Column] = [] # contains complete history of columns, incl dropped ones
|
|
123
122
|
self.cols_by_name: dict[str, Column] = {} # contains only user-facing (named) columns visible in this version
|
|
124
|
-
self.cols_by_id: dict[int, Column] = {} # contains only columns visible in this version
|
|
123
|
+
self.cols_by_id: dict[int, Column] = {} # contains only columns visible in this version
|
|
125
124
|
self.idx_md = tbl_md.index_md # needed for _create_tbl_md()
|
|
126
125
|
self.idxs_by_name: dict[str, TableVersion.IndexInfo] = {} # contains only actively maintained indices
|
|
127
126
|
self._init_schema(tbl_md, schema_version_md)
|
|
@@ -269,16 +268,6 @@ class TableVersion:
|
|
|
269
268
|
col.value_expr = exprs.Expr.from_dict(col_md.value_expr)
|
|
270
269
|
self._record_value_expr(col)
|
|
271
270
|
|
|
272
|
-
# if this is a stored proxy column, resolve the relationships with its proxy base.
|
|
273
|
-
if col_md.proxy_base is not None:
|
|
274
|
-
# proxy_base must have a strictly smaller id, so we must already have encountered it
|
|
275
|
-
# in traversal order; and if the proxy column is active at this version, then the
|
|
276
|
-
# proxy base must necessarily be active as well. This motivates the following assertion.
|
|
277
|
-
assert col_md.proxy_base in self.cols_by_id
|
|
278
|
-
base_col = self.cols_by_id[col_md.proxy_base]
|
|
279
|
-
base_col.stored_proxy = col
|
|
280
|
-
col.proxy_base = base_col
|
|
281
|
-
|
|
282
271
|
def _init_idxs(self, tbl_md: schema.TableMd) -> None:
|
|
283
272
|
self.idx_md = tbl_md.index_md
|
|
284
273
|
self.idxs_by_name = {}
|
|
@@ -544,16 +533,8 @@ class TableVersion:
|
|
|
544
533
|
dependent_user_cols = [c for c in col.dependent_cols if c.name is not None]
|
|
545
534
|
if len(dependent_user_cols) > 0:
|
|
546
535
|
raise excs.Error(
|
|
547
|
-
f'Cannot drop column
|
|
548
|
-
f'{", ".join(c.name for c in dependent_user_cols)}'
|
|
549
|
-
)
|
|
550
|
-
dependent_remotes = [remote for remote, col_mapping in self.remotes.items() if name in col_mapping]
|
|
551
|
-
if len(dependent_remotes) > 0:
|
|
552
|
-
raise excs.Error(
|
|
553
|
-
f'Cannot drop column `{name}` because the following remotes depend on it:\n'
|
|
554
|
-
f'{", ".join(str(r) for r in dependent_remotes)}'
|
|
555
|
-
)
|
|
556
|
-
assert col.stored_proxy is None # since there are no dependent remotes
|
|
536
|
+
f'Cannot drop column {name} because the following columns depend on it:\n',
|
|
537
|
+
f'{", ".join([c.name for c in dependent_user_cols])}')
|
|
557
538
|
|
|
558
539
|
# we're creating a new schema version
|
|
559
540
|
self.version += 1
|
|
@@ -964,88 +945,26 @@ class TableVersion:
|
|
|
964
945
|
|
|
965
946
|
@classmethod
|
|
966
947
|
def _init_remote(cls, remote_md: dict[str, Any]) -> Tuple[pixeltable.datatransfer.Remote, dict[str, str]]:
|
|
967
|
-
|
|
968
|
-
|
|
948
|
+
module = importlib.import_module(remote_md['module'])
|
|
949
|
+
remote_cls = getattr(module, remote_md['class'])
|
|
969
950
|
remote = remote_cls.from_dict(remote_md['remote_md'])
|
|
970
951
|
col_mapping = remote_md['col_mapping']
|
|
971
952
|
return remote, col_mapping
|
|
972
953
|
|
|
973
954
|
def link(self, remote: pixeltable.datatransfer.Remote, col_mapping: dict[str, str]) -> None:
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
cols_by_name = self.path.cols_by_name() # Includes base columns
|
|
978
|
-
stored_proxies_needed = []
|
|
979
|
-
for col_name in col_mapping.keys():
|
|
980
|
-
col = cols_by_name[col_name]
|
|
981
|
-
if col.col_type.is_media_type() and not (col.is_stored and col.compute_func) and not col.stored_proxy:
|
|
982
|
-
stored_proxies_needed.append(col)
|
|
955
|
+
timestamp = time.time()
|
|
956
|
+
self.version += 1
|
|
957
|
+
self.remotes[remote] = col_mapping
|
|
983
958
|
with Env.get().engine.begin() as conn:
|
|
984
|
-
self.
|
|
985
|
-
self.remotes[remote] = col_mapping
|
|
986
|
-
preceding_schema_version = None
|
|
987
|
-
if len(stored_proxies_needed) > 0:
|
|
988
|
-
_logger.info(f'Creating stored proxies for columns: {[col.name for col in stored_proxies_needed]}')
|
|
989
|
-
# Create stored proxies for columns that need one. Increment the schema version
|
|
990
|
-
# accordingly.
|
|
991
|
-
preceding_schema_version = self.schema_version
|
|
992
|
-
self.schema_version = self.version
|
|
993
|
-
proxy_cols = [self.create_stored_proxy(col) for col in stored_proxies_needed]
|
|
994
|
-
# Add the columns; this will also update table metadata.
|
|
995
|
-
# TODO Add to base tables
|
|
996
|
-
self._add_columns(proxy_cols, conn)
|
|
997
|
-
# We don't need to retain `UpdateStatus` since the stored proxies are intended to be
|
|
998
|
-
# invisible to the user.
|
|
999
|
-
self._update_md(time.time(), preceding_schema_version, conn)
|
|
1000
|
-
|
|
1001
|
-
def create_stored_proxy(self, col: Column) -> Column:
|
|
1002
|
-
from pixeltable import exprs
|
|
1003
|
-
|
|
1004
|
-
assert col.col_type.is_media_type() and not (col.is_stored and col.compute_func) and not col.stored_proxy
|
|
1005
|
-
proxy_col = Column(
|
|
1006
|
-
name=None,
|
|
1007
|
-
computed_with=exprs.ColumnRef(col).apply(lambda x: x, col_type=col.col_type),
|
|
1008
|
-
stored=True,
|
|
1009
|
-
col_id=self.next_col_id,
|
|
1010
|
-
sa_col_type=col.col_type.to_sa_type(),
|
|
1011
|
-
schema_version_add=self.schema_version
|
|
1012
|
-
)
|
|
1013
|
-
proxy_col.tbl = self
|
|
1014
|
-
self.next_col_id += 1
|
|
1015
|
-
col.stored_proxy = proxy_col
|
|
1016
|
-
proxy_col.proxy_base = col
|
|
1017
|
-
return proxy_col
|
|
959
|
+
self._update_md(timestamp, None, conn)
|
|
1018
960
|
|
|
1019
961
|
def unlink(self, remote: pixeltable.datatransfer.Remote) -> None:
|
|
1020
962
|
assert remote in self.remotes
|
|
1021
963
|
timestamp = time.time()
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
col_name
|
|
1025
|
-
for other_remote, col_mapping in self.remotes.items() if other_remote != remote
|
|
1026
|
-
for col_name in col_mapping.keys()
|
|
1027
|
-
}
|
|
1028
|
-
cols_by_name = self.path.cols_by_name() # Includes base columns
|
|
1029
|
-
stored_proxy_deletions_needed = [
|
|
1030
|
-
cols_by_name[col_name]
|
|
1031
|
-
for col_name in this_remote_col_names
|
|
1032
|
-
if col_name not in other_remote_col_names and cols_by_name[col_name].stored_proxy
|
|
1033
|
-
]
|
|
964
|
+
self.version += 1
|
|
965
|
+
del self.remotes[remote]
|
|
1034
966
|
with Env.get().engine.begin() as conn:
|
|
1035
|
-
self.
|
|
1036
|
-
del self.remotes[remote]
|
|
1037
|
-
preceding_schema_version = None
|
|
1038
|
-
if len(stored_proxy_deletions_needed) > 0:
|
|
1039
|
-
preceding_schema_version = self.schema_version
|
|
1040
|
-
self.schema_version = self.version
|
|
1041
|
-
proxy_cols = [col.stored_proxy for col in stored_proxy_deletions_needed]
|
|
1042
|
-
for col in stored_proxy_deletions_needed:
|
|
1043
|
-
assert col.stored_proxy is not None and col.stored_proxy.proxy_base == col
|
|
1044
|
-
col.stored_proxy.proxy_base = None
|
|
1045
|
-
col.stored_proxy = None
|
|
1046
|
-
# TODO Drop from base tables
|
|
1047
|
-
self._drop_columns(proxy_cols)
|
|
1048
|
-
self._update_md(timestamp, preceding_schema_version, conn)
|
|
967
|
+
self._update_md(timestamp, None, conn)
|
|
1049
968
|
|
|
1050
969
|
def get_remotes(self) -> dict[pixeltable.datatransfer.Remote, dict[str, str]]:
|
|
1051
970
|
return self.remotes
|
|
@@ -1151,15 +1070,15 @@ class TableVersion:
|
|
|
1151
1070
|
column_md[col.id] = schema.ColumnMd(
|
|
1152
1071
|
id=col.id, col_type=col.col_type.as_dict(), is_pk=col.is_pk,
|
|
1153
1072
|
schema_version_add=col.schema_version_add, schema_version_drop=col.schema_version_drop,
|
|
1154
|
-
value_expr=value_expr_dict, stored=col.stored
|
|
1155
|
-
proxy_base=col.proxy_base.id if col.proxy_base else None)
|
|
1073
|
+
value_expr=value_expr_dict, stored=col.stored)
|
|
1156
1074
|
return column_md
|
|
1157
1075
|
|
|
1158
1076
|
@classmethod
|
|
1159
1077
|
def _create_remotes_md(cls, remotes: dict['pixeltable.datatransfer.Remote', dict[str, str]]) -> list[dict[str, Any]]:
|
|
1160
1078
|
return [
|
|
1161
1079
|
{
|
|
1162
|
-
'
|
|
1080
|
+
'module': type(remote).__module__,
|
|
1081
|
+
'class': type(remote).__qualname__,
|
|
1163
1082
|
'remote_md': remote.to_dict(),
|
|
1164
1083
|
'col_mapping': col_mapping
|
|
1165
1084
|
}
|
|
@@ -106,14 +106,9 @@ class TableVersionPath:
|
|
|
106
106
|
if self.base is not None:
|
|
107
107
|
base_cols = self.base.columns()
|
|
108
108
|
# we only include base columns that don't conflict with one of our column names
|
|
109
|
-
result.extend(c for c in base_cols if c.name not in self.tbl_version.cols_by_name)
|
|
109
|
+
result.extend([c for c in base_cols if c.name not in self.tbl_version.cols_by_name])
|
|
110
110
|
return result
|
|
111
111
|
|
|
112
|
-
def cols_by_name(self) -> dict[str, Column]:
|
|
113
|
-
"""Return a dict of all user columns visible in this tbl version path, including columns from bases"""
|
|
114
|
-
cols = self.columns()
|
|
115
|
-
return {col.name: col for col in cols}
|
|
116
|
-
|
|
117
112
|
def get_column(self, name: str, include_bases: bool = True) -> Optional[Column]:
|
|
118
113
|
"""Return the column with the given name, or None if not found"""
|
|
119
114
|
col = self.tbl_version.cols_by_name.get(name)
|