Refactor puck handling for responses
Revised and optimized the `get_pucks_with_tell_position` endpoint to streamline logic and enhance clarity.
This commit is contained in:
parent
c45a46b07b
commit
ac38bc3bb6
@ -12,6 +12,7 @@ from app.schemas import (
|
|||||||
PuckWithTellPosition,
|
PuckWithTellPosition,
|
||||||
Sample,
|
Sample,
|
||||||
SetTellPosition,
|
SetTellPosition,
|
||||||
|
DataCollectionParameters,
|
||||||
)
|
)
|
||||||
from app.models import (
|
from app.models import (
|
||||||
Puck as PuckModel,
|
Puck as PuckModel,
|
||||||
@ -189,6 +190,86 @@ async def set_tell_positions(
|
|||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/with-tell-position", response_model=List[PuckWithTellPosition])
|
||||||
|
async def get_pucks_with_tell_position(db: Session = Depends(get_db)):
|
||||||
|
"""
|
||||||
|
Retrieve all pucks with a `tell_position` set (not null),
|
||||||
|
their associated samples, and the latest `tell_position` value (if any).
|
||||||
|
"""
|
||||||
|
# Step 1: Prepare a subquery to fetch the latest event timestamp for each
|
||||||
|
# puck with a non-null tell_position
|
||||||
|
latest_event_subquery = (
|
||||||
|
db.query(
|
||||||
|
PuckEventModel.puck_id,
|
||||||
|
func.max(PuckEventModel.timestamp).label("latest_timestamp"),
|
||||||
|
)
|
||||||
|
.filter(
|
||||||
|
PuckEventModel.tell_position.isnot(None)
|
||||||
|
) # Filter non-null tell_positions
|
||||||
|
.group_by(PuckEventModel.puck_id) # Group by puck
|
||||||
|
.subquery()
|
||||||
|
)
|
||||||
|
|
||||||
|
# Step 2: Query the pucks and their latest `tell_position` by joining the subquery
|
||||||
|
pucks_with_events = (
|
||||||
|
db.query(PuckModel, PuckEventModel, DewarModel)
|
||||||
|
.join(PuckEventModel, PuckModel.id == PuckEventModel.puck_id)
|
||||||
|
.join(
|
||||||
|
latest_event_subquery,
|
||||||
|
(PuckEventModel.puck_id == latest_event_subquery.c.puck_id)
|
||||||
|
& (PuckEventModel.timestamp == latest_event_subquery.c.latest_timestamp),
|
||||||
|
)
|
||||||
|
.outerjoin(
|
||||||
|
DewarModel, PuckModel.dewar_id == DewarModel.id
|
||||||
|
) # Outer join with DewarModel
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
|
||||||
|
if not pucks_with_events:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Step 3: Construct the response with pucks and their latest tell_position
|
||||||
|
results = []
|
||||||
|
for puck, event, dewar in pucks_with_events:
|
||||||
|
# Fetch associated samples for this puck
|
||||||
|
samples = db.query(SampleModel).filter(SampleModel.puck_id == puck.id).all()
|
||||||
|
|
||||||
|
# Construct the response model
|
||||||
|
results.append(
|
||||||
|
PuckWithTellPosition(
|
||||||
|
id=int(puck.id),
|
||||||
|
puck_name=str(puck.puck_name),
|
||||||
|
puck_type=str(puck.puck_type),
|
||||||
|
puck_location_in_dewar=str(puck.puck_location_in_dewar)
|
||||||
|
if puck.puck_location_in_dewar
|
||||||
|
else None,
|
||||||
|
dewar_id=int(puck.dewar_id) if puck.dewar_id else None,
|
||||||
|
dewar_name=str(dewar.dewar_name)
|
||||||
|
if dewar and dewar.dewar_name
|
||||||
|
else None,
|
||||||
|
samples=[
|
||||||
|
Sample(
|
||||||
|
id=sample.id,
|
||||||
|
sample_name=sample.sample_name,
|
||||||
|
position=sample.position,
|
||||||
|
puck_id=sample.puck_id,
|
||||||
|
data_collection_parameters=(
|
||||||
|
DataCollectionParameters(
|
||||||
|
**sample.data_collection_parameters
|
||||||
|
)
|
||||||
|
if isinstance(sample.data_collection_parameters, dict)
|
||||||
|
else sample.data_collection_parameters
|
||||||
|
),
|
||||||
|
)
|
||||||
|
for sample in samples
|
||||||
|
],
|
||||||
|
tell_position=str(event.tell_position) if event else None,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{puck_id}", response_model=PuckSchema)
|
@router.get("/{puck_id}", response_model=PuckSchema)
|
||||||
async def get_puck(puck_id: str, db: Session = Depends(get_db)):
|
async def get_puck(puck_id: str, db: Session = Depends(get_db)):
|
||||||
puck = db.query(PuckModel).filter(PuckModel.id == puck_id).first()
|
puck = db.query(PuckModel).filter(PuckModel.id == puck_id).first()
|
||||||
@ -403,60 +484,3 @@ async def get_pucks_by_slot(slot_identifier: str, db: Session = Depends(get_db))
|
|||||||
|
|
||||||
logger.info(f"Final response for slot {slot_identifier}: {results}")
|
logger.info(f"Final response for slot {slot_identifier}: {results}")
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
@router.get("/with-tell-position", response_model=List[PuckWithTellPosition])
|
|
||||||
async def get_pucks_with_tell_position(db: Session = Depends(get_db)):
|
|
||||||
"""
|
|
||||||
Retrieve all pucks with a `tell_position` set (not null),
|
|
||||||
their associated samples, and the latest `tell_position` value (if any).
|
|
||||||
"""
|
|
||||||
|
|
||||||
pucks_with_events = (
|
|
||||||
db.query(PuckModel, PuckEventModel)
|
|
||||||
.join(PuckEventModel, PuckModel.id == PuckEventModel.puck_id)
|
|
||||||
.filter(
|
|
||||||
PuckEventModel.tell_position.isnot(None)
|
|
||||||
) # Ensure only non-null tell_positions
|
|
||||||
.order_by(PuckEventModel.timestamp.desc()) # Get the most recent event
|
|
||||||
.distinct(PuckModel.id) # Ensure one row per puck (latest event is prioritized)
|
|
||||||
.all()
|
|
||||||
)
|
|
||||||
|
|
||||||
if not pucks_with_events:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=404,
|
|
||||||
detail="No pucks with a `tell_position` found.",
|
|
||||||
)
|
|
||||||
|
|
||||||
# Construct the response with pucks and their latest tell_position
|
|
||||||
results = []
|
|
||||||
for puck, event in pucks_with_events:
|
|
||||||
# Retrieve associated samples for this puck
|
|
||||||
samples = db.query(SampleModel).filter(SampleModel.puck_id == puck.id).all()
|
|
||||||
|
|
||||||
# Construct the response model
|
|
||||||
results.append(
|
|
||||||
PuckWithTellPosition(
|
|
||||||
id=int(puck.id), # Explicit casting
|
|
||||||
puck_name=str(puck.puck_name),
|
|
||||||
puck_type=str(puck.puck_type),
|
|
||||||
puck_location_in_dewar=str(puck.puck_location_in_dewar)
|
|
||||||
if puck.puck_location_in_dewar
|
|
||||||
else None,
|
|
||||||
dewar_id=int(puck.dewar_id) if puck.dewar_id else None,
|
|
||||||
samples=[
|
|
||||||
Sample(
|
|
||||||
id=sample.id,
|
|
||||||
sample_name=sample.sample_name,
|
|
||||||
position=sample.position,
|
|
||||||
)
|
|
||||||
for sample in samples
|
|
||||||
],
|
|
||||||
tell_position=str(event.tell_position)
|
|
||||||
if event
|
|
||||||
else None, # Include tell_position
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
return results
|
|
||||||
|
3446
testfunctions.ipynb
3446
testfunctions.ipynb
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user