pixeltable 0.4.0rc3__py3-none-any.whl → 0.4.1__py3-none-any.whl
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/__init__.py +1 -1
- pixeltable/__version__.py +2 -2
- pixeltable/catalog/__init__.py +9 -1
- pixeltable/catalog/catalog.py +333 -99
- pixeltable/catalog/column.py +28 -26
- pixeltable/catalog/globals.py +12 -0
- pixeltable/catalog/insertable_table.py +8 -8
- pixeltable/catalog/schema_object.py +6 -0
- pixeltable/catalog/table.py +111 -116
- pixeltable/catalog/table_version.py +36 -50
- pixeltable/catalog/table_version_handle.py +4 -1
- pixeltable/catalog/table_version_path.py +28 -4
- pixeltable/catalog/view.py +10 -18
- pixeltable/config.py +4 -0
- pixeltable/dataframe.py +10 -9
- pixeltable/env.py +5 -11
- pixeltable/exceptions.py +6 -0
- pixeltable/exec/exec_node.py +2 -0
- pixeltable/exec/expr_eval/expr_eval_node.py +4 -4
- pixeltable/exec/sql_node.py +47 -30
- pixeltable/exprs/column_property_ref.py +2 -1
- pixeltable/exprs/column_ref.py +7 -6
- pixeltable/exprs/expr.py +4 -4
- pixeltable/func/__init__.py +1 -0
- pixeltable/func/mcp.py +74 -0
- pixeltable/func/query_template_function.py +4 -2
- pixeltable/func/tools.py +12 -2
- pixeltable/func/udf.py +2 -2
- pixeltable/functions/__init__.py +1 -0
- pixeltable/functions/groq.py +108 -0
- pixeltable/functions/huggingface.py +8 -6
- pixeltable/functions/mistralai.py +2 -13
- pixeltable/functions/openai.py +1 -6
- pixeltable/functions/replicate.py +2 -2
- pixeltable/functions/util.py +6 -1
- pixeltable/globals.py +0 -2
- pixeltable/io/external_store.py +2 -2
- pixeltable/io/label_studio.py +4 -4
- pixeltable/io/table_data_conduit.py +1 -1
- pixeltable/metadata/__init__.py +1 -1
- pixeltable/metadata/converters/convert_37.py +15 -0
- pixeltable/metadata/notes.py +1 -0
- pixeltable/metadata/schema.py +5 -0
- pixeltable/plan.py +37 -121
- pixeltable/share/packager.py +2 -2
- pixeltable/type_system.py +30 -0
- {pixeltable-0.4.0rc3.dist-info → pixeltable-0.4.1.dist-info}/METADATA +1 -1
- {pixeltable-0.4.0rc3.dist-info → pixeltable-0.4.1.dist-info}/RECORD +51 -49
- pixeltable/utils/sample.py +0 -25
- {pixeltable-0.4.0rc3.dist-info → pixeltable-0.4.1.dist-info}/LICENSE +0 -0
- {pixeltable-0.4.0rc3.dist-info → pixeltable-0.4.1.dist-info}/WHEEL +0 -0
- {pixeltable-0.4.0rc3.dist-info → pixeltable-0.4.1.dist-info}/entry_points.txt +0 -0
pixeltable/catalog/column.py
CHANGED
|
@@ -42,11 +42,9 @@ class Column:
|
|
|
42
42
|
sa_errortype_col: Optional[sql.schema.Column]
|
|
43
43
|
_value_expr: Optional[exprs.Expr]
|
|
44
44
|
value_expr_dict: Optional[dict[str, Any]]
|
|
45
|
-
dependent_cols: set[Column]
|
|
46
45
|
# we store a TableVersion here, not a TableVersionHandle, because this column is owned by that TableVersion instance
|
|
47
46
|
# (re-resolving it later to a different instance doesn't make sense)
|
|
48
47
|
tbl: Optional[TableVersion]
|
|
49
|
-
# tbl: Optional[TableVersionHandle]
|
|
50
48
|
|
|
51
49
|
def __init__(
|
|
52
50
|
self,
|
|
@@ -62,6 +60,7 @@ class Column:
|
|
|
62
60
|
sa_col_type: Optional[sql.sqltypes.TypeEngine] = None,
|
|
63
61
|
records_errors: Optional[bool] = None,
|
|
64
62
|
value_expr_dict: Optional[dict[str, Any]] = None,
|
|
63
|
+
tbl: Optional[TableVersion] = None,
|
|
65
64
|
):
|
|
66
65
|
"""Column constructor.
|
|
67
66
|
|
|
@@ -86,6 +85,7 @@ class Column:
|
|
|
86
85
|
if name is not None and not is_valid_identifier(name):
|
|
87
86
|
raise excs.Error(f"Invalid column name: '{name}'")
|
|
88
87
|
self.name = name
|
|
88
|
+
self.tbl = tbl
|
|
89
89
|
if col_type is None and computed_with is None:
|
|
90
90
|
raise excs.Error(f'Column `{name}`: col_type is required if computed_with is not specified')
|
|
91
91
|
|
|
@@ -94,6 +94,7 @@ class Column:
|
|
|
94
94
|
if computed_with is not None:
|
|
95
95
|
value_expr = exprs.Expr.from_object(computed_with)
|
|
96
96
|
if value_expr is None:
|
|
97
|
+
# TODO: this shouldn't be a user-facing error
|
|
97
98
|
raise excs.Error(
|
|
98
99
|
f'Column {name}: computed_with needs to be a valid Pixeltable expression, '
|
|
99
100
|
f'but it is a {type(computed_with)}'
|
|
@@ -101,13 +102,15 @@ class Column:
|
|
|
101
102
|
else:
|
|
102
103
|
self._value_expr = value_expr.copy()
|
|
103
104
|
self.col_type = self._value_expr.col_type
|
|
105
|
+
if self._value_expr is not None and self.value_expr_dict is None:
|
|
106
|
+
self.value_expr_dict = self._value_expr.as_dict()
|
|
104
107
|
|
|
105
108
|
if col_type is not None:
|
|
106
109
|
self.col_type = col_type
|
|
107
110
|
assert self.col_type is not None
|
|
108
111
|
|
|
109
112
|
self.stored = stored
|
|
110
|
-
self.dependent_cols = set() # cols with value_exprs that reference us; set by TableVersion
|
|
113
|
+
# self.dependent_cols = set() # cols with value_exprs that reference us; set by TableVersion
|
|
111
114
|
self.id = col_id
|
|
112
115
|
self.is_pk = is_pk
|
|
113
116
|
self._media_validation = media_validation
|
|
@@ -124,36 +127,35 @@ class Column:
|
|
|
124
127
|
self.sa_errormsg_col = None
|
|
125
128
|
self.sa_errortype_col = None
|
|
126
129
|
|
|
127
|
-
|
|
130
|
+
def init_value_expr(self) -> None:
|
|
131
|
+
from pixeltable import exprs
|
|
132
|
+
|
|
133
|
+
if self._value_expr is not None or self.value_expr_dict is None:
|
|
134
|
+
return
|
|
135
|
+
self._value_expr = exprs.Expr.from_dict(self.value_expr_dict)
|
|
136
|
+
self._value_expr.bind_rel_paths()
|
|
137
|
+
if not self._value_expr.is_valid:
|
|
138
|
+
message = (
|
|
139
|
+
dedent(
|
|
140
|
+
f"""
|
|
141
|
+
The computed column {self.name!r} in table {self.tbl.name!r} is no longer valid.
|
|
142
|
+
{{validation_error}}
|
|
143
|
+
You can continue to query existing data from this column, but evaluating it on new data will raise an error.
|
|
144
|
+
""" # noqa: E501
|
|
145
|
+
)
|
|
146
|
+
.strip()
|
|
147
|
+
.format(validation_error=self._value_expr.validation_error)
|
|
148
|
+
)
|
|
149
|
+
warnings.warn(message, category=excs.PixeltableWarning, stacklevel=2)
|
|
128
150
|
|
|
129
151
|
@property
|
|
130
152
|
def value_expr(self) -> Optional[exprs.Expr]:
|
|
131
|
-
|
|
132
|
-
# TODO: instantiate expr in the c'tor and add an Expr.prepare() that can create additional state after the
|
|
133
|
-
# catalog has been fully loaded; that way, we encounter bugs in the serialization/deserialization logic earlier
|
|
134
|
-
if self.value_expr_dict is not None and self._value_expr is None:
|
|
135
|
-
from pixeltable import exprs
|
|
136
|
-
|
|
137
|
-
self._value_expr = exprs.Expr.from_dict(self.value_expr_dict)
|
|
138
|
-
self._value_expr.bind_rel_paths()
|
|
139
|
-
if not self._value_expr.is_valid:
|
|
140
|
-
message = (
|
|
141
|
-
dedent(
|
|
142
|
-
f"""
|
|
143
|
-
The computed column {self.name!r} in table {self.tbl.name!r} is no longer valid.
|
|
144
|
-
{{validation_error}}
|
|
145
|
-
You can continue to query existing data from this column, but evaluating it on new data will raise an error.
|
|
146
|
-
""" # noqa: E501
|
|
147
|
-
)
|
|
148
|
-
.strip()
|
|
149
|
-
.format(validation_error=self._value_expr.validation_error)
|
|
150
|
-
)
|
|
151
|
-
warnings.warn(message, category=excs.PixeltableWarning, stacklevel=2)
|
|
153
|
+
assert self.value_expr_dict is None or self._value_expr is not None
|
|
152
154
|
return self._value_expr
|
|
153
155
|
|
|
154
156
|
def set_value_expr(self, value_expr: exprs.Expr) -> None:
|
|
155
157
|
self._value_expr = value_expr
|
|
156
|
-
self.value_expr_dict =
|
|
158
|
+
self.value_expr_dict = self._value_expr.as_dict()
|
|
157
159
|
|
|
158
160
|
def check_value_expr(self) -> None:
|
|
159
161
|
assert self._value_expr is not None
|
pixeltable/catalog/globals.py
CHANGED
|
@@ -5,6 +5,7 @@ import enum
|
|
|
5
5
|
import itertools
|
|
6
6
|
import logging
|
|
7
7
|
from typing import Optional
|
|
8
|
+
from uuid import UUID
|
|
8
9
|
|
|
9
10
|
from typing_extensions import Self
|
|
10
11
|
|
|
@@ -21,6 +22,17 @@ _ROWID_COLUMN_NAME = '_rowid'
|
|
|
21
22
|
_PREDEF_SYMBOLS: Optional[set[str]] = None
|
|
22
23
|
|
|
23
24
|
|
|
25
|
+
@dataclasses.dataclass(frozen=True)
|
|
26
|
+
class QColumnId:
|
|
27
|
+
"""Qualified column id"""
|
|
28
|
+
|
|
29
|
+
tbl_id: UUID
|
|
30
|
+
col_id: int
|
|
31
|
+
|
|
32
|
+
# def __hash__(self) -> int:
|
|
33
|
+
# return hash((self.tbl_id, self.col_id))
|
|
34
|
+
|
|
35
|
+
|
|
24
36
|
@dataclasses.dataclass
|
|
25
37
|
class UpdateStatus:
|
|
26
38
|
"""
|
|
@@ -51,6 +51,7 @@ class InsertableTable(Table):
|
|
|
51
51
|
def __init__(self, dir_id: UUID, tbl_version: TableVersionHandle):
|
|
52
52
|
tbl_version_path = TableVersionPath(tbl_version)
|
|
53
53
|
super().__init__(tbl_version.id, dir_id, tbl_version.get().name, tbl_version_path)
|
|
54
|
+
self._tbl_version = tbl_version
|
|
54
55
|
|
|
55
56
|
@classmethod
|
|
56
57
|
def _display_name(cls) -> str:
|
|
@@ -103,8 +104,8 @@ class InsertableTable(Table):
|
|
|
103
104
|
Env.get().console_logger.info(f'Created table `{name}`.')
|
|
104
105
|
return tbl
|
|
105
106
|
|
|
106
|
-
def
|
|
107
|
-
md = super().
|
|
107
|
+
def _get_metadata(self) -> dict[str, Any]:
|
|
108
|
+
md = super()._get_metadata()
|
|
108
109
|
md['is_view'] = False
|
|
109
110
|
md['is_snapshot'] = False
|
|
110
111
|
return md
|
|
@@ -141,7 +142,7 @@ class InsertableTable(Table):
|
|
|
141
142
|
from pixeltable.catalog import Catalog
|
|
142
143
|
from pixeltable.io.table_data_conduit import UnkTableDataConduit
|
|
143
144
|
|
|
144
|
-
with Catalog.get().begin_xact(
|
|
145
|
+
with Catalog.get().begin_xact(tbl=self._tbl_version_path, for_write=True, lock_mutable_tree=True):
|
|
145
146
|
table = self
|
|
146
147
|
if source is None:
|
|
147
148
|
source = [kwargs]
|
|
@@ -171,7 +172,7 @@ class InsertableTable(Table):
|
|
|
171
172
|
from pixeltable.io.table_data_conduit import DFTableDataConduit
|
|
172
173
|
|
|
173
174
|
status = pxt.UpdateStatus()
|
|
174
|
-
with Catalog.get().begin_xact(
|
|
175
|
+
with Catalog.get().begin_xact(tbl=self._tbl_version_path, for_write=True, lock_mutable_tree=True):
|
|
175
176
|
if isinstance(data_source, DFTableDataConduit):
|
|
176
177
|
status += self._tbl_version.get().insert(
|
|
177
178
|
rows=None, df=data_source.pxt_df, print_stats=print_stats, fail_on_exception=fail_on_exception
|
|
@@ -189,7 +190,7 @@ class InsertableTable(Table):
|
|
|
189
190
|
|
|
190
191
|
def _validate_input_rows(self, rows: list[dict[str, Any]]) -> None:
|
|
191
192
|
"""Verify that the input rows match the table schema"""
|
|
192
|
-
valid_col_names = set(self.
|
|
193
|
+
valid_col_names = set(self._get_schema().keys())
|
|
193
194
|
reqd_col_names = set(self._tbl_version_path.tbl_version.get().get_required_col_names())
|
|
194
195
|
computed_col_names = set(self._tbl_version_path.tbl_version.get().get_computed_col_names())
|
|
195
196
|
for row in rows:
|
|
@@ -231,11 +232,10 @@ class InsertableTable(Table):
|
|
|
231
232
|
"""
|
|
232
233
|
from pixeltable.catalog import Catalog
|
|
233
234
|
|
|
234
|
-
with Catalog.get().begin_xact(
|
|
235
|
+
with Catalog.get().begin_xact(tbl=self._tbl_version_path, for_write=True, lock_mutable_tree=True):
|
|
235
236
|
return self._tbl_version.get().delete(where=where)
|
|
236
237
|
|
|
237
|
-
|
|
238
|
-
def _base_table(self) -> Optional['Table']:
|
|
238
|
+
def _get_base_table(self) -> Optional['Table']:
|
|
239
239
|
return None
|
|
240
240
|
|
|
241
241
|
@property
|
|
@@ -42,6 +42,12 @@ class SchemaObject:
|
|
|
42
42
|
|
|
43
43
|
def get_metadata(self) -> dict[str, Any]:
|
|
44
44
|
"""Returns metadata associated with this schema object."""
|
|
45
|
+
from pixeltable.catalog import Catalog
|
|
46
|
+
|
|
47
|
+
with Catalog.get().begin_xact(for_write=False):
|
|
48
|
+
return self._get_metadata()
|
|
49
|
+
|
|
50
|
+
def _get_metadata(self) -> dict[str, Any]:
|
|
45
51
|
return {'name': self._name, 'path': self._path()}
|
|
46
52
|
|
|
47
53
|
@classmethod
|