Skip to content

Commit e7de829

Browse files
authored
make sure empty strings cannot be added to doi and pmid (#735)
1 parent eae136c commit e7de829

File tree

5 files changed

+38
-2
lines changed

5 files changed

+38
-2
lines changed

store/neurostore/models/data.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ class BaseStudy(BaseMixin, db.Model):
178178
__table_args__ = (
179179
db.CheckConstraint(level.in_(["group", "meta"])),
180180
db.UniqueConstraint("doi", "pmid", name="doi_pmid"),
181+
db.CheckConstraint("pmid ~ '^(?=.*\\S).+$' OR name IS NULL"),
182+
db.CheckConstraint("doi ~ '^(?=.*\\S).+$' OR name IS NULL"),
181183
sa.Index("ix_base_study___ts_vector__", _ts_vector, postgresql_using="gin"),
182184
)
183185

@@ -280,6 +282,8 @@ class Study(BaseMixin, db.Model):
280282

281283
__table_args__ = (
282284
db.CheckConstraint(level.in_(["group", "meta"])),
285+
db.CheckConstraint("pmid ~ '^(?=.*\\S).+$' OR name IS NULL"),
286+
db.CheckConstraint("doi ~ '^(?=.*\\S).+$' OR name IS NULL"),
283287
sa.Index("ix_study___ts_vector__", _ts_vector, postgresql_using="gin"),
284288
)
285289

store/neurostore/resources/data.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,8 +457,13 @@ def post(self):
457457
)
458458
hashed_results = {(bs.doi or "") + (bs.pmid or ""): bs for bs in results}
459459
for study_data in data:
460-
lookup_hash = study_data.get("doi", "") + study_data.get("pmid", "")
461-
record = hashed_results.get(lookup_hash)
460+
doi = study_data.get("doi", "") or ""
461+
pmid = study_data.get("pmid", "") or ""
462+
lookup_hash = doi + pmid
463+
if lookup_hash == "" or lookup_hash.isspace():
464+
record = None
465+
else:
466+
record = hashed_results.get(lookup_hash)
462467
if record is None:
463468
with db.session.no_autoflush:
464469
record = self.__class__.update_or_create(study_data, flush=False)

store/neurostore/schemas/data.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,15 @@ class Meta:
331331
"level",
332332
)
333333

334+
@pre_load
335+
def check_nulls(self, data, **kwargs):
336+
"""ensure data is not empty string or whitespace"""
337+
for attr in ["pmid", "pmcid", "doi"]:
338+
val = data.get(attr, None)
339+
if val is not None and (val == "" or val.isspace()):
340+
data[attr] = None
341+
return data
342+
334343

335344
class StudySchema(BaseDataSchema):
336345
metadata = fields.Dict(attribute="metadata_", dump_only=True)
@@ -378,6 +387,15 @@ class Meta:
378387
"level",
379388
)
380389

390+
@pre_load
391+
def check_nulls(self, data, **kwargs):
392+
"""ensure data is not empty string or whitespace"""
393+
for attr in ["pmid", "pmcid", "doi"]:
394+
val = data.get(attr, None)
395+
if val is not None and (val == "" or val.isspace()):
396+
data[attr] = None
397+
return data
398+
381399

382400
class StudysetSchema(BaseDataSchema):
383401
# serialize

store/neurostore/tests/api/test_base_studies.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ def test_post_list_of_studies(auth_client, ingest_neuroquery):
2424
{
2525
"name": "another new name",
2626
},
27+
{
28+
"doi": "",
29+
"pmid": "",
30+
"name": "no ids",
31+
}
2732
]
2833

2934
result = auth_client.post("/api/base-studies/", data=test_input)

store/neurostore/tests/api/test_studies.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ def test_clone_studies_with_data(auth_client, ingest_neurosynth, session):
126126
study_data["analyses"].append(
127127
{"name": "new analysis", "points": second_analysis_points}
128128
)
129+
study_data["pmid"] = ""
130+
study_data["doi"] = ""
129131

130132
resp = auth_client.post(
131133
f"/api/studies/?source_id={study_entry.id}",
@@ -138,6 +140,8 @@ def test_clone_studies_with_data(auth_client, ingest_neurosynth, session):
138140
assert data["analyses"][0]["points"][0]["coordinates"] == [0, 0, 0]
139141
assert data["analyses"][1]["points"][0]["coordinates"] == [0, 0, 0]
140142
assert "new analysis" in [a["name"] for a in data["analyses"]]
143+
assert data["pmid"] is None
144+
assert data["doi"] is None
141145

142146

143147
def test_private_studies(user_data, auth_clients, session):

0 commit comments

Comments
 (0)