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.

Files changed (126) hide show
  1. {pixeltable-0.2.7 → pixeltable-0.2.8}/PKG-INFO +2 -2
  2. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/__version__.py +2 -2
  3. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/column.py +0 -6
  4. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/table.py +15 -42
  5. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/table_version.py +15 -96
  6. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/table_version_path.py +1 -6
  7. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/datatransfer/label_studio.py +108 -182
  8. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/datatransfer/remote.py +3 -31
  9. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/env.py +4 -8
  10. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/io/globals.py +2 -3
  11. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/metadata/__init__.py +1 -1
  12. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/metadata/schema.py +0 -3
  13. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/tool/create_test_db_dump.py +3 -5
  14. {pixeltable-0.2.7 → pixeltable-0.2.8}/pyproject.toml +2 -2
  15. pixeltable-0.2.7/pixeltable/metadata/converters/convert_15.py +0 -29
  16. pixeltable-0.2.7/pixeltable/metadata/converters/util.py +0 -63
  17. {pixeltable-0.2.7 → pixeltable-0.2.8}/LICENSE +0 -0
  18. {pixeltable-0.2.7 → pixeltable-0.2.8}/README.md +0 -0
  19. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/__init__.py +0 -0
  20. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/__init__.py +0 -0
  21. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/catalog.py +0 -0
  22. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/dir.py +0 -0
  23. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/globals.py +0 -0
  24. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/insertable_table.py +0 -0
  25. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/named_function.py +0 -0
  26. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/path.py +0 -0
  27. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/path_dict.py +0 -0
  28. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/schema_object.py +0 -0
  29. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/catalog/view.py +0 -0
  30. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/dataframe.py +0 -0
  31. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/datatransfer/__init__.py +0 -0
  32. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exceptions.py +0 -0
  33. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/__init__.py +0 -0
  34. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/aggregation_node.py +0 -0
  35. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/cache_prefetch_node.py +0 -0
  36. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/component_iteration_node.py +0 -0
  37. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/data_row_batch.py +0 -0
  38. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/exec_context.py +0 -0
  39. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/exec_node.py +0 -0
  40. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/expr_eval_node.py +0 -0
  41. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/in_memory_data_node.py +0 -0
  42. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/media_validation_node.py +0 -0
  43. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exec/sql_scan_node.py +0 -0
  44. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/__init__.py +0 -0
  45. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/arithmetic_expr.py +0 -0
  46. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/array_slice.py +0 -0
  47. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/column_property_ref.py +0 -0
  48. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/column_ref.py +0 -0
  49. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/comparison.py +0 -0
  50. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/compound_predicate.py +0 -0
  51. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/data_row.py +0 -0
  52. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/expr.py +0 -0
  53. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/expr_set.py +0 -0
  54. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/function_call.py +0 -0
  55. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/globals.py +0 -0
  56. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/image_member_access.py +0 -0
  57. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/in_predicate.py +0 -0
  58. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/inline_array.py +0 -0
  59. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/inline_dict.py +0 -0
  60. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/is_null.py +0 -0
  61. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/json_mapper.py +0 -0
  62. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/json_path.py +0 -0
  63. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/literal.py +0 -0
  64. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/object_ref.py +0 -0
  65. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/predicate.py +0 -0
  66. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/row_builder.py +0 -0
  67. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/rowid_ref.py +0 -0
  68. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/similarity_expr.py +0 -0
  69. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/type_cast.py +0 -0
  70. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/exprs/variable.py +0 -0
  71. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/ext/__init__.py +0 -0
  72. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/ext/functions/whisperx.py +0 -0
  73. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/ext/functions/yolox.py +0 -0
  74. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/func/__init__.py +0 -0
  75. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/func/aggregate_function.py +0 -0
  76. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/func/callable_function.py +0 -0
  77. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/func/expr_template_function.py +0 -0
  78. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/func/function.py +0 -0
  79. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/func/function_registry.py +0 -0
  80. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/func/globals.py +0 -0
  81. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/func/signature.py +0 -0
  82. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/func/udf.py +0 -0
  83. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/__init__.py +0 -0
  84. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/eval.py +0 -0
  85. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/fireworks.py +0 -0
  86. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/huggingface.py +0 -0
  87. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/image.py +0 -0
  88. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/openai.py +0 -0
  89. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/pil/image.py +0 -0
  90. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/string.py +0 -0
  91. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/together.py +0 -0
  92. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/util.py +0 -0
  93. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/functions/video.py +0 -0
  94. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/globals.py +0 -0
  95. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/index/__init__.py +0 -0
  96. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/index/base.py +0 -0
  97. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/index/btree.py +0 -0
  98. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/index/embedding_index.py +0 -0
  99. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/io/__init__.py +0 -0
  100. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/io/hf_datasets.py +0 -0
  101. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/io/pandas.py +0 -0
  102. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/io/parquet.py +0 -0
  103. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/iterators/__init__.py +0 -0
  104. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/iterators/base.py +0 -0
  105. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/iterators/document.py +0 -0
  106. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/iterators/video.py +0 -0
  107. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/metadata/converters/convert_10.py +0 -0
  108. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/metadata/converters/convert_12.py +0 -0
  109. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/metadata/converters/convert_13.py +0 -0
  110. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/metadata/converters/convert_14.py +0 -0
  111. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/plan.py +0 -0
  112. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/store.py +0 -0
  113. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/tool/create_test_video.py +0 -0
  114. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/type_system.py +0 -0
  115. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/__init__.py +0 -0
  116. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/arrow.py +0 -0
  117. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/coco.py +0 -0
  118. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/documents.py +0 -0
  119. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/filecache.py +0 -0
  120. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/help.py +0 -0
  121. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/http_server.py +0 -0
  122. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/media_store.py +0 -0
  123. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/pytorch.py +0 -0
  124. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/s3.py +0 -0
  125. {pixeltable-0.2.7 → pixeltable-0.2.8}/pixeltable/utils/sql.py +0 -0
  126. {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.7
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.3)
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.7"
3
- __version_tuple__ = (0, 2, 7)
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
- if remote in self._get_remotes():
740
- raise excs.Error(f'That remote is already linked to table `{self.get_name()}`: {remote}')
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(push_cols.keys(), pull_cols.keys())}
747
- self._validate_remote(push_cols, pull_cols, col_mapping, is_col_mapping_user_specified)
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
- all_remotes = self._get_remotes()
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
- for remote in remotes:
786
- self.tbl_version_path.tbl_version.unlink(remote)
787
- print(f'Unlinked remote {remote} from table `{self.get_name()}`.')
788
- if delete_remote_data:
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; expecting `{r_col_type}`)'
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; expecting `{r_col_type}`)'
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, both system and user
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 `{name}` because the following columns depend on it:\n'
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
- remote_cls = resolve_symbol(remote_md['class'])
968
- assert isinstance(remote_cls, type) and issubclass(remote_cls, pixeltable.datatransfer.Remote)
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
- # All of the media columns being linked need to either be stored, computed columns or have stored proxies.
975
- # This ensures that the media in those columns resides in the media cache, where it can be served.
976
- # First determine which columns (if any) need stored proxies, but don't have one yet.
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.version += 1
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
- this_remote_col_names = list(self.remotes[remote].keys())
1023
- other_remote_col_names = {
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.version += 1
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
- 'class': f'{type(remote).__module__}.{type(remote).__qualname__}',
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)