Skip to content

Commit

Permalink
preload analyses
Browse files Browse the repository at this point in the history
  • Loading branch information
jdkent committed Nov 20, 2023
1 parent 864c14d commit 4fe28ce
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 27 deletions.
86 changes: 59 additions & 27 deletions store/neurostore/resources/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,11 @@ def post_nested_record_update(record):
return record

@classmethod
def update_or_create(cls, data, id=None, commit=True):
def load_nested_records(cls, data, record=None):
return data

@classmethod
def update_or_create(cls, data, id=None, user=None, record=None, commit=True):
"""
scenerios:
1. cloning a study
Expand All @@ -91,7 +95,7 @@ def update_or_create(cls, data, id=None, commit=True):
# Store all models so we can atomically update in one commit
to_commit = []

current_user = get_current_user()
current_user = user or get_current_user()
if not current_user:
current_user = create_user()

Expand All @@ -104,31 +108,35 @@ def update_or_create(cls, data, id=None, commit=True):

# allow compose bot to make changes
compose_bot = current_app.config["COMPOSE_AUTH0_CLIENT_ID"] + "@clients"
if id is None:
if id is None and record is None:
record = cls._model()
record.user = current_user
else:
elif record is None:
record = cls._model.query.filter_by(id=id).first()
if record is None:
abort(422)
elif (
record.user_id != current_user.external_id
and not only_ids
and current_user.external_id != compose_bot
):
abort(403)
elif only_ids:
to_commit.append(record)

if commit:
db.session.add_all(to_commit)
try:
db.session.commit()
except SQLAlchemyError:
db.session.rollback()
abort(400)

return record

data = cls.load_nested_records(data, record)

if (
not sa.inspect(record).pending
and record.user != current_user
and not only_ids
and current_user.external_id != compose_bot
):
abort(403)
elif only_ids:
to_commit.append(record)

if commit:
db.session.add_all(to_commit)
try:
db.session.commit()
except SQLAlchemyError:
db.session.rollback()
abort(400)

return record

# Update all non-nested attributes
for k, v in data.items():
Expand Down Expand Up @@ -171,13 +179,37 @@ def update_or_create(cls, data, id=None, commit=True):
ResCls = getattr(viewdata, res_name)
if data.get(field) is not None:
if isinstance(data.get(field), list):
nested = [
ResCls.update_or_create(rec, commit=False)
for rec in data.get(field)
]
nested = []
for rec in data.get(field):
id = None
if isinstance(rec, dict) and rec.get("id"):
id = rec.get("id")
elif isinstance(rec, str):
id = rec
if data.get("preloaded_studies") and id:
nested_record = data["preloaded_studies"].get(id)
else:
nested_record = None
nested.append(
ResCls.update_or_create(
rec, user=current_user, record=nested_record, commit=False
)
)
to_commit.extend(nested)
else:
nested = ResCls.update_or_create(data.get(field), commit=False)
id = None
rec = data.get(field)
if isinstance(rec, dict) and rec.get("id"):
id = rec.get("id")
elif isinstance(rec, str):
id = rec
if data.get("preloaded_studies") and id:
nested_record = data["preloaded_studies"].get(id)
else:
nested_record = None
nested = ResCls.update_or_create(
rec, user=current_user, record=nested_record, commit=False
)
to_commit.append(nested)

setattr(record, field, nested)
Expand Down
26 changes: 26 additions & 0 deletions store/neurostore/resources/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,32 @@ class StudysetsView(ObjectView, ListView):
_multi_search = ("name", "description")
_search_fields = ("name", "description", "publication", "doi", "pmid")

@classmethod
def load_nested_records(cls, data, record=None):
if not data or not data.get("studies"):
return data
studies = data.get("studies")
existing_studies = []
for s in studies:
if isinstance(s, dict) and s.get("id"):
existing_studies.append(s.get("id"))
elif isinstance(s, str):
existing_studies.append(s)
study_results = Study.query.filter(
Study.id.in_(existing_studies)
).options(
joinedload(Study.analyses),
joinedload(Study.user),
).all()
study_dict = {s.id: s for s in study_results}
# Modification of data in place
if study_dict:
data['preloaded_studies'] = study_dict
return data




def view_search(self, q, args):
# check if results should be nested
nested = True if args.get("nested") else False
Expand Down

0 comments on commit 4fe28ce

Please sign in to comment.