La siguiente consulta debería hacer el trabajo:
from sqlalchemy import func
# ...
query = (
select(
[
func.json_build_object(
"id",
events.c.id,
"title",
events.c.title,
"location",
func.json_agg(
func.json_build_object(
"city",
locations.c.city,
"street",
locations.c.street,
"building",
locations.c.building,
)
),
"location_all_columns_example",
func.json_agg(func.json_build_object(
*itertools.chain(*[(_.name, _) for _ in locations.c])
)),
"activity",
func.json_agg(
func.json_build_object(
"name",
activities.c.name,
)
),
)
]
)
.select_from(events.join(locations).join(activities))
.where(
and_(
events.c.id == pk,
locations.c.id == events.c.location_id,
activities.c.id == events.c.activities_id,
)
)
.order_by(desc(events.c.created_at))
.group_by(events.c.id) # !!! <- IMPORTANT
)
Tenga en cuenta que necesita el group_by
cláusula.