pixeltable 0.2.5__py3-none-any.whl → 0.2.7__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 +20 -9
- pixeltable/__version__.py +3 -0
- pixeltable/catalog/column.py +23 -7
- pixeltable/catalog/insertable_table.py +32 -19
- pixeltable/catalog/table.py +210 -20
- pixeltable/catalog/table_version.py +272 -111
- pixeltable/catalog/table_version_path.py +6 -1
- pixeltable/dataframe.py +184 -110
- pixeltable/datatransfer/__init__.py +1 -0
- pixeltable/datatransfer/label_studio.py +526 -0
- pixeltable/datatransfer/remote.py +113 -0
- pixeltable/env.py +213 -79
- pixeltable/exec/__init__.py +2 -1
- pixeltable/exec/data_row_batch.py +6 -7
- pixeltable/exec/expr_eval_node.py +28 -28
- pixeltable/exec/sql_scan_node.py +7 -6
- pixeltable/exprs/__init__.py +4 -3
- pixeltable/exprs/column_ref.py +11 -2
- pixeltable/exprs/comparison.py +39 -1
- pixeltable/exprs/data_row.py +7 -0
- pixeltable/exprs/expr.py +26 -19
- pixeltable/exprs/function_call.py +17 -18
- pixeltable/exprs/globals.py +14 -2
- pixeltable/exprs/image_member_access.py +9 -28
- pixeltable/exprs/in_predicate.py +96 -0
- pixeltable/exprs/inline_array.py +13 -11
- pixeltable/exprs/inline_dict.py +15 -13
- pixeltable/exprs/row_builder.py +7 -1
- pixeltable/exprs/similarity_expr.py +67 -0
- pixeltable/ext/functions/whisperx.py +30 -0
- pixeltable/ext/functions/yolox.py +16 -0
- pixeltable/func/__init__.py +0 -2
- pixeltable/func/aggregate_function.py +5 -2
- pixeltable/func/callable_function.py +57 -13
- pixeltable/func/expr_template_function.py +14 -3
- pixeltable/func/function.py +35 -4
- pixeltable/func/signature.py +5 -15
- pixeltable/func/udf.py +8 -12
- pixeltable/functions/fireworks.py +9 -4
- pixeltable/functions/huggingface.py +48 -5
- pixeltable/functions/openai.py +49 -11
- pixeltable/functions/pil/image.py +61 -64
- pixeltable/functions/together.py +32 -6
- pixeltable/functions/util.py +0 -43
- pixeltable/functions/video.py +46 -8
- pixeltable/globals.py +443 -0
- pixeltable/index/__init__.py +1 -0
- pixeltable/index/base.py +9 -2
- pixeltable/index/btree.py +54 -0
- pixeltable/index/embedding_index.py +91 -15
- pixeltable/io/__init__.py +4 -0
- pixeltable/io/globals.py +59 -0
- pixeltable/{utils → io}/hf_datasets.py +48 -17
- pixeltable/io/pandas.py +148 -0
- pixeltable/{utils → io}/parquet.py +58 -33
- pixeltable/iterators/__init__.py +1 -1
- pixeltable/iterators/base.py +8 -4
- pixeltable/iterators/document.py +225 -93
- pixeltable/iterators/video.py +16 -9
- pixeltable/metadata/__init__.py +8 -4
- pixeltable/metadata/converters/convert_12.py +3 -0
- pixeltable/metadata/converters/convert_13.py +41 -0
- pixeltable/metadata/converters/convert_14.py +13 -0
- pixeltable/metadata/converters/convert_15.py +29 -0
- pixeltable/metadata/converters/util.py +63 -0
- pixeltable/metadata/schema.py +12 -6
- pixeltable/plan.py +11 -24
- pixeltable/store.py +16 -23
- pixeltable/tool/create_test_db_dump.py +49 -14
- pixeltable/type_system.py +27 -58
- pixeltable/utils/coco.py +94 -0
- pixeltable/utils/documents.py +42 -12
- pixeltable/utils/http_server.py +70 -0
- pixeltable-0.2.7.dist-info/METADATA +137 -0
- pixeltable-0.2.7.dist-info/RECORD +126 -0
- {pixeltable-0.2.5.dist-info → pixeltable-0.2.7.dist-info}/WHEEL +1 -1
- pixeltable/client.py +0 -600
- pixeltable/exprs/image_similarity_predicate.py +0 -58
- pixeltable/func/batched_function.py +0 -53
- pixeltable/func/nos_function.py +0 -202
- pixeltable/tests/conftest.py +0 -171
- pixeltable/tests/ext/test_yolox.py +0 -21
- pixeltable/tests/functions/test_fireworks.py +0 -43
- pixeltable/tests/functions/test_functions.py +0 -60
- pixeltable/tests/functions/test_huggingface.py +0 -158
- pixeltable/tests/functions/test_openai.py +0 -162
- pixeltable/tests/functions/test_together.py +0 -112
- pixeltable/tests/test_audio.py +0 -65
- pixeltable/tests/test_catalog.py +0 -27
- pixeltable/tests/test_client.py +0 -21
- pixeltable/tests/test_component_view.py +0 -379
- pixeltable/tests/test_dataframe.py +0 -440
- pixeltable/tests/test_dirs.py +0 -107
- pixeltable/tests/test_document.py +0 -120
- pixeltable/tests/test_exprs.py +0 -802
- pixeltable/tests/test_function.py +0 -332
- pixeltable/tests/test_index.py +0 -138
- pixeltable/tests/test_migration.py +0 -44
- pixeltable/tests/test_nos.py +0 -54
- pixeltable/tests/test_snapshot.py +0 -231
- pixeltable/tests/test_table.py +0 -1343
- pixeltable/tests/test_transactional_directory.py +0 -42
- pixeltable/tests/test_types.py +0 -52
- pixeltable/tests/test_video.py +0 -159
- pixeltable/tests/test_view.py +0 -535
- pixeltable/tests/utils.py +0 -442
- pixeltable/utils/clip.py +0 -18
- pixeltable-0.2.5.dist-info/METADATA +0 -128
- pixeltable-0.2.5.dist-info/RECORD +0 -139
- {pixeltable-0.2.5.dist-info → pixeltable-0.2.7.dist-info}/LICENSE +0 -0
|
@@ -1,379 +0,0 @@
|
|
|
1
|
-
from typing import Dict, Any, List, Tuple
|
|
2
|
-
|
|
3
|
-
import PIL
|
|
4
|
-
import numpy as np
|
|
5
|
-
import pandas as pd
|
|
6
|
-
import pytest
|
|
7
|
-
|
|
8
|
-
import pixeltable as pxt
|
|
9
|
-
from pixeltable import exceptions as excs
|
|
10
|
-
from pixeltable.iterators import ComponentIterator
|
|
11
|
-
from pixeltable.iterators.video import FrameIterator
|
|
12
|
-
from pixeltable.tests.utils import assert_resultset_eq, get_test_video_files, validate_update_status
|
|
13
|
-
from pixeltable.type_system import IntType, VideoType, JsonType
|
|
14
|
-
|
|
15
|
-
class ConstantImgIterator(ComponentIterator):
|
|
16
|
-
"""Component iterator that generates a fixed number of all-black 1280x720 images."""
|
|
17
|
-
def __init__(self, video: str, num_frames: int = 10):
|
|
18
|
-
self.img = PIL.Image.new('RGB', (1280, 720))
|
|
19
|
-
self.next_frame_idx = 0
|
|
20
|
-
self.num_frames = num_frames
|
|
21
|
-
self.pos_msec = 0.0
|
|
22
|
-
self.pos_frame = 0.0
|
|
23
|
-
|
|
24
|
-
@classmethod
|
|
25
|
-
def input_schema(cls) -> Dict[str, pxt.ColumnType]:
|
|
26
|
-
return {
|
|
27
|
-
'video': VideoType(nullable=False),
|
|
28
|
-
'fps': pxt.FloatType()
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
@classmethod
|
|
32
|
-
def output_schema(cls, *args: Any, **kwargs: Any) -> Tuple[Dict[str, pxt.ColumnType], List[str]]:
|
|
33
|
-
return {
|
|
34
|
-
'frame_idx': IntType(),
|
|
35
|
-
'pos_msec': pxt.FloatType(),
|
|
36
|
-
'pos_frame': pxt.FloatType(),
|
|
37
|
-
'frame': pxt.ImageType(),
|
|
38
|
-
}, ['frame']
|
|
39
|
-
|
|
40
|
-
def __next__(self) -> Dict[str, Any]:
|
|
41
|
-
while True:
|
|
42
|
-
if self.next_frame_idx == self.num_frames:
|
|
43
|
-
raise StopIteration
|
|
44
|
-
result = {
|
|
45
|
-
'frame_idx': self.next_frame_idx,
|
|
46
|
-
'pos_msec': self.pos_msec,
|
|
47
|
-
'pos_frame': self.pos_frame,
|
|
48
|
-
'frame': self.img,
|
|
49
|
-
}
|
|
50
|
-
self.next_frame_idx += 1
|
|
51
|
-
return result
|
|
52
|
-
|
|
53
|
-
def close(self) -> None:
|
|
54
|
-
pass
|
|
55
|
-
|
|
56
|
-
def set_pos(self, pos: int) -> None:
|
|
57
|
-
if pos == self.next_frame_idx:
|
|
58
|
-
return
|
|
59
|
-
self.next_frame_idx = pos
|
|
60
|
-
|
|
61
|
-
class TestComponentView:
|
|
62
|
-
def test_basic(self, test_client: pxt.Client) -> None:
|
|
63
|
-
cl = test_client
|
|
64
|
-
# create video table
|
|
65
|
-
schema = {'video': VideoType(), 'angle': IntType(), 'other_angle': IntType()}
|
|
66
|
-
video_t = cl.create_table('video_tbl', schema)
|
|
67
|
-
video_filepaths = get_test_video_files()
|
|
68
|
-
|
|
69
|
-
# cannot add 'pos' column
|
|
70
|
-
with pytest.raises(excs.Error) as excinfo:
|
|
71
|
-
video_t.add_column(pos=IntType())
|
|
72
|
-
assert 'reserved' in str(excinfo.value)
|
|
73
|
-
|
|
74
|
-
# parameter missing
|
|
75
|
-
with pytest.raises(excs.Error) as excinfo:
|
|
76
|
-
args = {'fps': 1}
|
|
77
|
-
_ = cl.create_view('test_view', video_t, iterator_class=FrameIterator, iterator_args=args)
|
|
78
|
-
assert 'missing a required argument' in str(excinfo.value)
|
|
79
|
-
|
|
80
|
-
# bad parameter type
|
|
81
|
-
with pytest.raises(excs.Error) as excinfo:
|
|
82
|
-
args = {'video': video_t.video, 'fps': '1'}
|
|
83
|
-
_ = cl.create_view('test_view', video_t, iterator_class=FrameIterator, iterator_args=args)
|
|
84
|
-
assert 'expected float' in str(excinfo.value)
|
|
85
|
-
|
|
86
|
-
# bad parameter type
|
|
87
|
-
with pytest.raises(excs.Error) as excinfo:
|
|
88
|
-
args = {'video': 1, 'fps': 1}
|
|
89
|
-
_ = cl.create_view('test_view', video_t, iterator_class=FrameIterator, iterator_args=args)
|
|
90
|
-
assert 'expected file path' in str(excinfo.value)
|
|
91
|
-
|
|
92
|
-
# create frame view
|
|
93
|
-
args = {'video': video_t.video, 'fps': 1}
|
|
94
|
-
view_t = cl.create_view('test_view', video_t, iterator_class=FrameIterator, iterator_args=args)
|
|
95
|
-
# computed column that references a column from the base
|
|
96
|
-
view_t.add_column(angle2=view_t.angle + 1)
|
|
97
|
-
# computed column that references an unstored and a stored computed view column
|
|
98
|
-
view_t.add_column(v1=view_t.frame.rotate(view_t.angle2), stored=True)
|
|
99
|
-
# computed column that references a stored computed column from the view
|
|
100
|
-
view_t.add_column(v2=view_t.frame_idx - 1)
|
|
101
|
-
# computed column that references an unstored view column and a column from the base; the stored value
|
|
102
|
-
# cannot be materialized in SQL directly
|
|
103
|
-
view_t.add_column(v3=view_t.frame.rotate(video_t.other_angle), stored=True)
|
|
104
|
-
|
|
105
|
-
# and load data
|
|
106
|
-
rows = [{'video': p, 'angle': 30, 'other_angle': -30} for p in video_filepaths]
|
|
107
|
-
status = video_t.insert(rows)
|
|
108
|
-
assert status.num_excs == 0
|
|
109
|
-
# pos and frame_idx are identical
|
|
110
|
-
res = view_t.select(view_t.pos, view_t.frame_idx).collect().to_pandas()
|
|
111
|
-
assert np.all(res['pos'] == res['frame_idx'])
|
|
112
|
-
|
|
113
|
-
video_url = video_t.select(video_t.video.fileurl).show(0)[0, 0]
|
|
114
|
-
result = view_t.where(view_t.video == video_url).select(view_t.frame, view_t.frame_idx) \
|
|
115
|
-
.collect()
|
|
116
|
-
result = view_t.where(view_t.video == video_url).select(view_t.frame_idx).order_by(view_t.frame_idx) \
|
|
117
|
-
.collect().to_pandas()
|
|
118
|
-
assert len(result) > 0
|
|
119
|
-
assert np.all(result['frame_idx'] == pd.Series(range(len(result))))
|
|
120
|
-
|
|
121
|
-
def test_add_column(self, test_client: pxt.Client) -> None:
|
|
122
|
-
cl = test_client
|
|
123
|
-
# create video table
|
|
124
|
-
video_t = cl.create_table('video_tbl', {'video': VideoType()})
|
|
125
|
-
video_filepaths = get_test_video_files()
|
|
126
|
-
# create frame view
|
|
127
|
-
args = {'video': video_t.video, 'fps': 1}
|
|
128
|
-
view_t = cl.create_view('test_view', video_t, iterator_class=FrameIterator, iterator_args=args)
|
|
129
|
-
|
|
130
|
-
rows = [{'video': p} for p in video_filepaths]
|
|
131
|
-
video_t.insert(rows)
|
|
132
|
-
# adding a non-computed column backfills it with nulls
|
|
133
|
-
view_t.add_column(annotation=JsonType(nullable=True))
|
|
134
|
-
assert view_t.count() == view_t.where(view_t.annotation == None).count()
|
|
135
|
-
# adding more data via the base table sets the column values to null
|
|
136
|
-
video_t.insert(rows)
|
|
137
|
-
_ = view_t.where(view_t.annotation == None).count()
|
|
138
|
-
assert view_t.count() == view_t.where(view_t.annotation == None).count()
|
|
139
|
-
|
|
140
|
-
with pytest.raises(excs.Error) as excinfo:
|
|
141
|
-
view_t.add_column(annotation=JsonType(nullable=False))
|
|
142
|
-
assert 'must be nullable' in str(excinfo.value)
|
|
143
|
-
|
|
144
|
-
def test_update(self, test_client: pxt.Client) -> None:
|
|
145
|
-
cl = test_client
|
|
146
|
-
# create video table
|
|
147
|
-
video_t = cl.create_table('video_tbl', {'video': VideoType()})
|
|
148
|
-
# create frame view with manually updated column
|
|
149
|
-
args = {'video': video_t.video, 'fps': 1}
|
|
150
|
-
view_t = cl.create_view(
|
|
151
|
-
'test_view', video_t, schema={'annotation': JsonType(nullable=True)},
|
|
152
|
-
iterator_class=FrameIterator, iterator_args=args)
|
|
153
|
-
|
|
154
|
-
video_filepaths = get_test_video_files()
|
|
155
|
-
rows = [{'video': p} for p in video_filepaths]
|
|
156
|
-
status = video_t.insert(rows)
|
|
157
|
-
assert status.num_excs == 0
|
|
158
|
-
import urllib
|
|
159
|
-
video_url = urllib.parse.urljoin('file:', urllib.request.pathname2url(video_filepaths[0]))
|
|
160
|
-
validate_update_status(
|
|
161
|
-
view_t.update({'annotation': {'a': 1}}, where=view_t.video == video_url),
|
|
162
|
-
expected_rows=view_t.where(view_t.video == video_url).count())
|
|
163
|
-
assert view_t.where(view_t.annotation != None).count() == view_t.where(view_t.video == video_url).count()
|
|
164
|
-
|
|
165
|
-
# batch update with _rowid works
|
|
166
|
-
validate_update_status(
|
|
167
|
-
view_t.batch_update(
|
|
168
|
-
[{'annotation': {'a': 1}, '_rowid': (1, 0)}, {'annotation': {'a': 1}, '_rowid': (1, 1)}]),
|
|
169
|
-
expected_rows=2)
|
|
170
|
-
with pytest.raises(AssertionError):
|
|
171
|
-
# malformed _rowid
|
|
172
|
-
view_t.batch_update([{'annotation': {'a': 1}, '_rowid': (1,)}])
|
|
173
|
-
|
|
174
|
-
with pytest.raises(excs.Error) as excinfo:
|
|
175
|
-
_ = cl.create_view(
|
|
176
|
-
'bad_view', video_t, schema={'annotation': JsonType(nullable=False)},
|
|
177
|
-
iterator_class=FrameIterator, iterator_args=args)
|
|
178
|
-
assert 'must be nullable' in str(excinfo.value)
|
|
179
|
-
|
|
180
|
-
# break up the snapshot tests for better (future) parallelization
|
|
181
|
-
def test_snapshot1(self, test_client: pxt.Client) -> None:
|
|
182
|
-
has_column = False
|
|
183
|
-
has_filter = False
|
|
184
|
-
for reload_md in [False, True]:
|
|
185
|
-
cl = pxt.Client(reload=True)
|
|
186
|
-
self.run_snapshot_test(cl, has_column=has_column, has_filter=has_filter, reload_md=reload_md)
|
|
187
|
-
|
|
188
|
-
def test_snapshot2(self, test_client: pxt.Client) -> None:
|
|
189
|
-
has_column = True
|
|
190
|
-
has_filter = False
|
|
191
|
-
for reload_md in [False, True]:
|
|
192
|
-
cl = pxt.Client(reload=True)
|
|
193
|
-
self.run_snapshot_test(cl, has_column=has_column, has_filter=has_filter, reload_md=reload_md)
|
|
194
|
-
|
|
195
|
-
def test_snapshot3(self, test_client: pxt.Client) -> None:
|
|
196
|
-
has_column = False
|
|
197
|
-
has_filter = True
|
|
198
|
-
for reload_md in [False, True]:
|
|
199
|
-
cl = pxt.Client(reload=True)
|
|
200
|
-
self.run_snapshot_test(cl, has_column=has_column, has_filter=has_filter, reload_md=reload_md)
|
|
201
|
-
|
|
202
|
-
def test_snapshot4(self, test_client: pxt.Client) -> None:
|
|
203
|
-
has_column = True
|
|
204
|
-
has_filter = True
|
|
205
|
-
for reload_md in [False, True]:
|
|
206
|
-
cl = pxt.Client(reload=True)
|
|
207
|
-
self.run_snapshot_test(cl, has_column=has_column, has_filter=has_filter, reload_md=reload_md)
|
|
208
|
-
|
|
209
|
-
def run_snapshot_test(self, cl: pxt.Client, has_column: bool, has_filter: bool, reload_md: bool) -> None:
|
|
210
|
-
base_path = 'video_tbl'
|
|
211
|
-
view_path = 'test_view'
|
|
212
|
-
snap_path = 'test_snap'
|
|
213
|
-
|
|
214
|
-
# create video table
|
|
215
|
-
video_t = cl.create_table(base_path, {'video': VideoType(), 'margin': IntType()})
|
|
216
|
-
video_filepaths = get_test_video_files()
|
|
217
|
-
rows = [{'video': path, 'margin': i * 10} for i, path in enumerate(video_filepaths)]
|
|
218
|
-
status = video_t.insert(rows)
|
|
219
|
-
assert status.num_rows == len(rows)
|
|
220
|
-
assert status.num_excs == 0
|
|
221
|
-
|
|
222
|
-
# create frame view with a computed column
|
|
223
|
-
args = {'video': video_t.video}
|
|
224
|
-
view_t = cl.create_view(
|
|
225
|
-
view_path, video_t, iterator_class=ConstantImgIterator, iterator_args=args, is_snapshot=False)
|
|
226
|
-
view_t.add_column(
|
|
227
|
-
cropped=view_t.frame.crop([view_t.margin, view_t.margin, view_t.frame.width, view_t.frame.height]),
|
|
228
|
-
stored=True)
|
|
229
|
-
snap_col_expr = [view_t.cropped.width * view_t.cropped.height] if has_column else []
|
|
230
|
-
view_query = \
|
|
231
|
-
view_t.select(
|
|
232
|
-
view_t.margin, view_t.frame.width, view_t.frame.height, view_t.cropped.width,
|
|
233
|
-
view_t.cropped.height, *snap_col_expr)\
|
|
234
|
-
.order_by(view_t.video, view_t.pos)
|
|
235
|
-
if has_filter:
|
|
236
|
-
view_query = view_query.where(view_t.frame_idx < 10)
|
|
237
|
-
orig_resultset = view_query.collect()
|
|
238
|
-
|
|
239
|
-
# create snapshot of view
|
|
240
|
-
filter = view_t.frame_idx < 10 if has_filter else None
|
|
241
|
-
schema = {'c1': view_t.cropped.width * view_t.cropped.height} if has_column else {}
|
|
242
|
-
snap_t = cl.create_view(snap_path, view_t, schema=schema, filter=filter, is_snapshot=True)
|
|
243
|
-
snap_cols = [snap_t.c1] if has_column else []
|
|
244
|
-
snap_query = \
|
|
245
|
-
snap_t.select(
|
|
246
|
-
snap_t.margin, snap_t.frame.width, snap_t.frame.height, snap_t.cropped.width,
|
|
247
|
-
snap_t.cropped.height, *snap_cols)\
|
|
248
|
-
.order_by(snap_t.video, snap_t.pos)
|
|
249
|
-
assert_resultset_eq(snap_query.collect(), orig_resultset)
|
|
250
|
-
|
|
251
|
-
if reload_md:
|
|
252
|
-
cl = pxt.Client(reload=True)
|
|
253
|
-
video_t = cl.get_table(base_path)
|
|
254
|
-
snap_t = cl.get_table(snap_path)
|
|
255
|
-
snap_cols = [snap_t.c1] if has_column else []
|
|
256
|
-
snap_query = \
|
|
257
|
-
snap_t.select(
|
|
258
|
-
snap_t.margin, snap_t.frame.width, snap_t.frame.height, snap_t.cropped.width,
|
|
259
|
-
snap_t.cropped.height, *snap_cols) \
|
|
260
|
-
.order_by(snap_t.video, snap_t.pos)
|
|
261
|
-
|
|
262
|
-
# snapshot is unaffected by base insert()
|
|
263
|
-
status = video_t.insert(rows)
|
|
264
|
-
assert status.num_excs == 0
|
|
265
|
-
assert_resultset_eq(snap_query.collect(), orig_resultset)
|
|
266
|
-
|
|
267
|
-
# snapshot is unaffected by base update()
|
|
268
|
-
status = video_t.update({'margin': video_t.margin + 1})
|
|
269
|
-
assert status.num_excs == 0
|
|
270
|
-
assert_resultset_eq(snap_query.collect(), orig_resultset)
|
|
271
|
-
|
|
272
|
-
# snapshot is unaffected by base delete()
|
|
273
|
-
status = video_t.delete()
|
|
274
|
-
assert status.num_excs == 0
|
|
275
|
-
assert_resultset_eq(snap_query.collect(), orig_resultset)
|
|
276
|
-
|
|
277
|
-
cl.drop_table(snap_path)
|
|
278
|
-
cl.drop_table(view_path)
|
|
279
|
-
cl.drop_table(base_path)
|
|
280
|
-
|
|
281
|
-
def test_chained_views(self, test_client: pxt.Client) -> None:
|
|
282
|
-
"""Component view followed by a standard view"""
|
|
283
|
-
cl = test_client
|
|
284
|
-
# create video table
|
|
285
|
-
schema = {'video': VideoType(), 'int1': IntType(), 'int2': IntType()}
|
|
286
|
-
video_t = cl.create_table('video_tbl', schema)
|
|
287
|
-
video_filepaths = get_test_video_files()
|
|
288
|
-
|
|
289
|
-
# create first view
|
|
290
|
-
args = {'video': video_t.video}
|
|
291
|
-
v1 = cl.create_view('test_view', video_t, iterator_class=ConstantImgIterator, iterator_args=args)
|
|
292
|
-
# computed column that references stored base column
|
|
293
|
-
v1.add_column(int3=v1.int1 + 1)
|
|
294
|
-
# stored computed column that references an unstored and a stored computed view column
|
|
295
|
-
v1.add_column(img1=v1.frame.crop([v1.int3, v1.int3, v1.frame.width, v1.frame.height]), stored=True)
|
|
296
|
-
# computed column that references a stored computed view column
|
|
297
|
-
v1.add_column(int4=v1.frame_idx + 1)
|
|
298
|
-
# unstored computed column that references an unstored and a stored computed view column
|
|
299
|
-
v1.add_column(img2=v1.frame.crop([v1.int4, v1.int4, v1.frame.width, v1.frame.height]), stored=False)
|
|
300
|
-
|
|
301
|
-
# create second view
|
|
302
|
-
v2 = cl.create_view('chained_view', v1)
|
|
303
|
-
# computed column that references stored video_t column
|
|
304
|
-
v2.add_column(int5=v2.int1 + 1)
|
|
305
|
-
v2.add_column(int6=v2.int2 + 1)
|
|
306
|
-
# stored computed column that references a stored base column and a stored computed view column;
|
|
307
|
-
# indirectly references int1
|
|
308
|
-
v2.add_column(img3=v2.img1.crop([v2.int5, v2.int5, v2.img1.width, v2.img1.height]), stored=True)
|
|
309
|
-
# stored computed column that references an unstored base column and a manually updated column from video_t;
|
|
310
|
-
# indirectly references int2
|
|
311
|
-
v2.add_column(img4=v2.img2.crop([v2.int6, v2.int6, v2.img2.width, v2.img2.height]), stored=True)
|
|
312
|
-
# comuted column that indirectly references int1 and int2
|
|
313
|
-
v2.add_column(int7=v2.img3.width + v2.img4.width)
|
|
314
|
-
|
|
315
|
-
def check_view():
|
|
316
|
-
assert_resultset_eq(
|
|
317
|
-
v1.select(v1.int3).order_by(v1.video, v1.pos).collect(),
|
|
318
|
-
v1.select(v1.int1 + 1).order_by(v1.video, v1.pos).collect())
|
|
319
|
-
assert_resultset_eq(
|
|
320
|
-
v1.select(v1.int4).order_by(v1.video, v1.pos).collect(),
|
|
321
|
-
v1.select(v1.frame_idx + 1).order_by(v1.video, v1.pos).collect())
|
|
322
|
-
assert_resultset_eq(
|
|
323
|
-
v1\
|
|
324
|
-
.select(v1.video, v1.img1.width, v1.img1.height)\
|
|
325
|
-
.order_by(v1.video, v1.pos).collect(),
|
|
326
|
-
v1\
|
|
327
|
-
.select(v1.video, v1.frame.width - v1.int1 - 1, v1.frame.height - v1.int1 - 1)\
|
|
328
|
-
.order_by(v1.video, v1.pos).collect())
|
|
329
|
-
assert_resultset_eq(
|
|
330
|
-
v2.select(v2.int5).order_by(v2.video, v2.pos).collect(),
|
|
331
|
-
v2.select(v2.int1 + 1).order_by(v2.video, v2.pos).collect())
|
|
332
|
-
assert_resultset_eq(
|
|
333
|
-
v2.select(v2.int6).order_by(v2.video, v2.pos).collect(),
|
|
334
|
-
v2.select(v2.int2 + 1).order_by(v2.video, v2.pos).collect())
|
|
335
|
-
assert_resultset_eq(
|
|
336
|
-
v2 \
|
|
337
|
-
.select(v2.video, v2.img3.width, v2.img3.height) \
|
|
338
|
-
.order_by(v2.video, v2.pos).collect(),
|
|
339
|
-
v2 \
|
|
340
|
-
.select(v2.video, v2.frame.width - v2.int1 * 2 - 2, v2.frame.height - v2.int1 * 2 - 2) \
|
|
341
|
-
.order_by(v2.video, v2.pos).collect())
|
|
342
|
-
assert_resultset_eq(
|
|
343
|
-
v2 \
|
|
344
|
-
.select(v2.video, v2.img4.width, v2.img4.height) \
|
|
345
|
-
.order_by(v2.video, v2.pos).collect(),
|
|
346
|
-
v2 \
|
|
347
|
-
.select(
|
|
348
|
-
v2.video, v2.frame.width - v2.frame_idx - v2.int2 - 2,
|
|
349
|
-
v2.frame.height - v2.frame_idx - v2.int2 - 2) \
|
|
350
|
-
.order_by(v2.video, v2.pos).collect())
|
|
351
|
-
assert_resultset_eq(
|
|
352
|
-
v2.select(v2.int7).order_by(v2.video, v2.pos).collect(),
|
|
353
|
-
v2.select(v2.img3.width + v2.img4.width).order_by(v2.video, v2.pos).collect())
|
|
354
|
-
assert_resultset_eq(
|
|
355
|
-
v2.select(v2.int7).order_by(v2.video, v2.pos).collect(),
|
|
356
|
-
v2.select(v2.frame.width - v2.int1 * 2 - 2 + v2.frame.width - v2.frame_idx - v2.int2 - 2)\
|
|
357
|
-
.order_by(v2.video, v2.pos).collect())
|
|
358
|
-
|
|
359
|
-
# load data
|
|
360
|
-
rows = [{'video': p, 'int1': i, 'int2': len(video_filepaths) - i} for i, p in enumerate(video_filepaths)]
|
|
361
|
-
status = video_t.insert(rows)
|
|
362
|
-
assert status.num_rows == video_t.count() + v1.count() + v2.count()
|
|
363
|
-
check_view()
|
|
364
|
-
|
|
365
|
-
# update int1: propagates to int3, img1, int5, img3, int7
|
|
366
|
-
# TODO: how to test that img4 doesn't get recomputed as part of the computation of int7?
|
|
367
|
-
# need to collect more runtime stats (eg, called functions)
|
|
368
|
-
import urllib
|
|
369
|
-
video_url = urllib.parse.urljoin('file:', urllib.request.pathname2url(video_filepaths[0]))
|
|
370
|
-
status = video_t.update({'int1': video_t.int1 + 1}, where=video_t.video == video_url)
|
|
371
|
-
assert status.num_rows == 1 + v1.where(v1.video == video_url).count() + v2.where(v2.video == video_url).count()
|
|
372
|
-
assert sorted('int1 int3 img1 int5 img3 int7'.split()) == sorted([str.split('.')[1] for str in status.updated_cols])
|
|
373
|
-
check_view()
|
|
374
|
-
|
|
375
|
-
# update int2: propagates to img4, int6, int7
|
|
376
|
-
status = video_t.update({'int2': video_t.int2 + 1}, where=video_t.video == video_url)
|
|
377
|
-
assert status.num_rows == 1 + v2.where(v2.video == video_url).count()
|
|
378
|
-
assert sorted('int2 img4 int6 int7'.split()) == sorted([str.split('.')[1] for str in status.updated_cols])
|
|
379
|
-
check_view()
|