10
10
OnModuleOffsetLocationSequenceComponent ,
11
11
OnLabwareOffsetLocationSequenceComponent ,
12
12
LabwareOffsetLocationSequenceComponents ,
13
+ LabwareOffsetLocationSequence ,
13
14
)
14
- from opentrons .types import DeckSlotName
15
15
16
16
from robot_server .persistence .tables import (
17
17
labware_offset_table ,
@@ -59,9 +59,9 @@ def add(self, offset: StoredLabwareOffset) -> None:
59
59
with self ._sql_engine .begin () as transaction :
60
60
offset_row_id = (
61
61
transaction .execute (
62
- sqlalchemy .insert (labware_offset_table )
63
- . values ( _pydantic_to_sql_offset (offset ) )
64
- . returning ( labware_offset_table . c . row_id )
62
+ sqlalchemy .insert (labware_offset_table ). values (
63
+ _pydantic_to_sql_offset (offset )
64
+ )
65
65
)
66
66
.one ()
67
67
.row_id
@@ -82,7 +82,7 @@ def search(
82
82
self ,
83
83
id_filter : str | DoNotFilterType = DO_NOT_FILTER ,
84
84
definition_uri_filter : str | DoNotFilterType = DO_NOT_FILTER ,
85
- location_slot_name_filter : DeckSlotName | DoNotFilterType = DO_NOT_FILTER ,
85
+ location_addressable_area_filter : str | DoNotFilterType = DO_NOT_FILTER ,
86
86
location_module_model_filter : (
87
87
ModuleModel | None | DoNotFilterType
88
88
) = DO_NOT_FILTER ,
@@ -111,48 +111,72 @@ def search(
111
111
filter_statement = filter_statement .where (
112
112
labware_offset_table .c .definition_uri == definition_uri_filter
113
113
)
114
- if location_slot_name_filter is not DO_NOT_FILTER :
115
- filter_statement = filter_statement .where (
116
- filter_statement .where (
117
- labware_offset_location_sequence_components_table .c .component_kind
118
- == "onAddressableArea"
114
+ if location_addressable_area_filter is not DO_NOT_FILTER :
115
+ if location_addressable_area_filter is not None :
116
+ filter_statement = filter_statement .where (
117
+ filter_statement .where (
118
+ labware_offset_location_sequence_components_table .c .component_kind
119
+ == "onAddressableArea"
120
+ )
121
+ .where (
122
+ labware_offset_location_sequence_components_table .c .primary_component_value
123
+ == location_addressable_area_filter
124
+ )
125
+ .exists ()
119
126
)
120
- .where (
121
- labware_offset_location_sequence_components_table .c .primary_component_value
122
- == location_slot_name_filter .value
127
+ else :
128
+ filter_statement = filter_statement .where (
129
+ sqlalchemy .not_ (
130
+ filter_statement .where (
131
+ labware_offset_location_sequence_components_table .c .component_kind
132
+ == "onAddressableArea"
133
+ ).exists ()
134
+ )
123
135
)
124
- .exists ()
125
- )
126
136
if location_module_model_filter is not DO_NOT_FILTER :
127
- location_module_model_filter_value = (
128
- location_module_model_filter .value
129
- if location_module_model_filter is not None
130
- else None
131
- )
132
- filter_statement = filter_statement .where (
133
- filter_statement .where (
134
- labware_offset_location_sequence_components_table .c .component_kind
135
- == "onModule"
137
+ if location_module_model_filter is not None :
138
+ filter_statement = filter_statement .where (
139
+ filter_statement .where (
140
+ labware_offset_location_sequence_components_table .c .component_kind
141
+ == "onModule"
142
+ )
143
+ .where (
144
+ labware_offset_location_sequence_components_table .c .primary_component_value
145
+ == location_module_model_filter .value
146
+ )
147
+ .exists ()
136
148
)
137
- .where (
138
- labware_offset_location_sequence_components_table .c .primary_component_value
139
- == location_module_model_filter .value
149
+ else :
150
+ filter_statement = filter_statement .where (
151
+ sqlalchemy .not_ (
152
+ filter_statement .where (
153
+ labware_offset_location_sequence_components_table .c .component_kind
154
+ == "onModule"
155
+ ).exists ()
156
+ )
140
157
)
141
- .exists ()
142
- )
143
158
if location_definition_uri_filter is not DO_NOT_FILTER :
144
- filter_statement = filter_statement .where (
145
- filter_statement .where (
146
- labware_offset_location_sequence_components_table .c .component_kind
147
- == "onLabware"
159
+ if location_definition_uri_filter is not None :
160
+ filter_statement = filter_statement .where (
161
+ filter_statement .where (
162
+ labware_offset_location_sequence_components_table .c .component_kind
163
+ == "onLabware"
164
+ )
165
+ .where (
166
+ labware_offset_location_sequence_components_table .c .primary_component_value
167
+ == location_definition_uri_filter
168
+ )
169
+ .exists ()
148
170
)
149
- .where (
150
- labware_offset_location_sequence_components_table .c .primary
151
- - component_value
152
- == location_definition_uri_filter
171
+ else :
172
+ filter_statement = filter_statement .where (
173
+ sqlalchemy .not_ (
174
+ filter_statement .where (
175
+ labware_offset_location_sequence_components_table .c .component_kind
176
+ == "onLabware"
177
+ ).exists ()
178
+ )
153
179
)
154
- .exists ()
155
- )
156
180
157
181
filter_statement = filter_statement .order_by (
158
182
labware_offset_table .c .row_id
@@ -167,14 +191,20 @@ def delete(self, offset_id: str) -> StoredLabwareOffset:
167
191
"""Delete a labware offset by its ID. Return what was just deleted."""
168
192
with self ._sql_engine .begin () as transaction :
169
193
try :
170
- row_to_delete = transaction .execute (
171
- sqlalchemy .select (labware_offset_table ).where (
172
- labware_offset_table .c .offset_id == offset_id
194
+ offset_rows = transaction .execute (
195
+ sqlalchemy .select (labware_offset_table )
196
+ .join (
197
+ labware_offset_location_sequence_components_table ,
198
+ labware_offset_table .c .row_id
199
+ == labware_offset_location_sequence_components_table .c .offset_id ,
173
200
)
174
- ).one ()
201
+ .where (labware_offset_table .c .offset_id == offset_id )
202
+ ).all ()
175
203
except sqlalchemy .exc .NoResultFound :
176
204
raise LabwareOffsetNotFoundError (bad_offset_id = offset_id ) from None
177
- if not row_to_delete .active :
205
+ if len (offset_rows ) == 0 :
206
+ raise LabwareOffsetNotFoundError (bad_offset_id = offset_id )
207
+ if not offset_rows [0 ].active :
178
208
# Already soft-deleted.
179
209
raise LabwareOffsetNotFoundError (bad_offset_id = offset_id )
180
210
@@ -184,18 +214,7 @@ def delete(self, offset_id: str) -> StoredLabwareOffset:
184
214
.values (active = False )
185
215
)
186
216
187
- location_sequence = transaction .execute (
188
- sqlalchemy .get (labware_offset_location_sequence_components_table )
189
- .where (
190
- labware_offset_location_sequence_components_table .c .offset_id
191
- == row_to_delete .row_id
192
- )
193
- .order_by (
194
- labware_offset_location_sequence_components_table .c .sequence_ordinal
195
- )
196
- ).all ()
197
-
198
- return _sql_to_pydantic (row_to_delete , location_sequence )
217
+ return next (_collate_sql_to_pydantic (offset_rows ))
199
218
200
219
def delete_all (self ) -> None :
201
220
"""Delete all labware offsets."""
@@ -217,15 +236,15 @@ def _sql_sequence_component_to_pydantic_sequence_component(
217
236
component_row : sqlalchemy .engine .Row ,
218
237
) -> LabwareOffsetLocationSequenceComponents :
219
238
if component_row .component_kind == "onLabware" :
220
- yield OnLabwareOffsetLocationSequenceComponent (
239
+ return OnLabwareOffsetLocationSequenceComponent (
221
240
labwareUri = component_row .primary_component_value
222
241
)
223
242
elif component_row .component_kind == "onModule" :
224
- yield OnModuleOffsetLocationSequenceComponent (
243
+ return OnModuleOffsetLocationSequenceComponent (
225
244
moduleModel = ModuleModel (component_row .primary_component_value )
226
245
)
227
246
elif component_row .component_kind == "onAddressableArea" :
228
- yield OnAddressableAreaOffsetLocationSequenceComponent (
247
+ return OnAddressableAreaOffsetLocationSequenceComponent (
229
248
addressableAreaName = component_row .primary_component_value
230
249
)
231
250
else :
@@ -234,7 +253,7 @@ def _sql_sequence_component_to_pydantic_sequence_component(
234
253
235
254
def _collate_sql_locations (
236
255
first_row : sqlalchemy .engine .Row , rest_rows : Iterator [sqlalchemy .engine .Row ]
237
- ) -> tuple [LabwareOffsetLocationSequence , Optional [ sqlalchemy .engine .Row ] ]:
256
+ ) -> tuple [LabwareOffsetLocationSequence , sqlalchemy .engine .Row | None ]:
238
257
offset_id = first_row .offset_id
239
258
location_sequence : list [LabwareOffsetLocationSequenceComponents ] = [
240
259
_sql_sequence_component_to_pydantic_sequence_component (first_row )
@@ -244,7 +263,7 @@ def _collate_sql_locations(
244
263
row = next (rest_rows )
245
264
except StopIteration :
246
265
return location_sequence , None
247
- if row .offset_id != first_row . offset_id :
266
+ if row .offset_id != offset_id :
248
267
return location_sequence , row
249
268
location_sequence .append (
250
269
_sql_sequence_component_to_pydantic_sequence_component (row )
@@ -253,7 +272,7 @@ def _collate_sql_locations(
253
272
254
273
def _sql_to_pydantic (
255
274
first_row : sqlalchemy .engine .Row , rest_rows : Iterator [sqlalchemy .engine .Row ]
256
- ) -> tuple [StoredLabwareOffset , Optional [ sqlalchemy .engine .Row ] ]:
275
+ ) -> tuple [StoredLabwareOffset , sqlalchemy .engine .Row | None ]:
257
276
location_sequence , next_row = _collate_sql_locations (first_row , rest_rows )
258
277
return (
259
278
StoredLabwareOffset (
@@ -275,7 +294,7 @@ def _collate_sql_to_pydantic(
275
294
query_results : list [sqlalchemy .engine .Row ],
276
295
) -> Iterator [StoredLabwareOffset ]:
277
296
row_iter = iter (query_results )
278
- row = next (row_iter )
297
+ row : sqlalchemy . engine . Row | None = next (row_iter )
279
298
while row :
280
299
result , row = _sql_to_pydantic (row , row_iter )
281
300
yield result
0 commit comments