Skip to content

Commit

Permalink
Merge pull request #172 from jverswijver/allow_nullable_fk_as_seconda…
Browse files Browse the repository at this point in the history
…ry_attr

feat: ✨ allow nullable fk as secondary attr in forms
  • Loading branch information
A-Baji authored Mar 20, 2024
2 parents d5aa349 + efba26a commit d2e3c27
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 50 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

Observes [Semantic Versioning](https://semver.org/spec/v2.0.0.html) standard and [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) convention.

## [0.8.11] - TBD

### Fixed

- bug with forms that was preventing nullable foreign keys from being null in sci-viz[#172](https://github.com/datajoint/pharus/pull/172)

## [0.8.10] - 2023-11-16

### Fixed
Expand Down Expand Up @@ -334,6 +340,7 @@ Observes [Semantic Versioning](https://semver.org/spec/v2.0.0.html) standard and
- Support for DataJoint attribute types: `varchar`, `int`, `float`, `datetime`, `date`, `time`, `decimal`, `uuid`.
- Check dependency utility to determine child table references.

[0.8.11]: https://github.com/datajoint/pharus/compare/0.8.9...0.8.11
[0.8.10]: https://github.com/datajoint/pharus/compare/0.8.9...0.8.10
[0.8.9]: https://github.com/datajoint/pharus/compare/0.8.8...0.8.9
[0.8.8]: https://github.com/datajoint/pharus/compare/0.8.7...0.8.8
Expand Down
2 changes: 1 addition & 1 deletion docker-compose-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ services:
set -e
if echo "${AS_SCRIPT}" | grep -i true &>/dev/null; then
echo "------ SYNTAX TESTS ------"
PKG_DIR=/opt/conda/lib/python${PY_VER}/site-packages/pharus
PKG_DIR=/main/pharus
flake8 $${PKG_DIR} --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 /main/tests --count --select=E9,F63,F7,F82 --show-source --statistics
echo "------ UNIT TESTS ------"
Expand Down
87 changes: 55 additions & 32 deletions pharus/component_interface.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""This module is a GUI component library of various common interfaces."""

from base64 import b64decode
import json
import datajoint as dj
Expand Down Expand Up @@ -217,25 +218,27 @@ def __init__(self, *args, **kwargs):
)
self.fields_map = self.component_config.get("map")
self.tables = [
getattr(
dj.VirtualModule(
s,
s,
connection=self.connection,
),
t[0],
)
if len(t) == 1
else getattr(
(
getattr(
dj.VirtualModule(
s,
s,
connection=self.connection,
),
t[0],
),
t[1],
)
if len(t) == 1
else getattr(
getattr(
dj.VirtualModule(
s,
s,
connection=self.connection,
),
t[0],
),
t[1],
)
)
for s, t in (
(
Expand Down Expand Up @@ -265,6 +268,13 @@ def __init__(self, *args, **kwargs):
self.datatype_lookup = {
k: v[1] for t in self.tables for k, v in t.heading.attributes.items()
}
self.nullable_lookup = [
k
for t in self.tables
for k, v in t.heading.attributes.items()
if v.nullable
]
print(self.nullable_lookup, flush=True)

if "presets" in self.component_config:
lcls = locals()
Expand Down Expand Up @@ -305,7 +315,12 @@ def fields_route(self):
source_fields = {
**{
(p_name := f"{p.database}.{dj.utils.to_camel_case(p.table_name)}"): {
"values": [NumpyEncoder.dumps(row) for row in p.fetch("KEY")],
"values": (
[NumpyEncoder.dumps(row) for row in p.fetch("KEY")]
if not all(k in self.nullable_lookup for k in p.primary_key)
else [NumpyEncoder.dumps(row) for row in p.fetch("KEY")]
+ [NumpyEncoder.dumps({k: None for k in p.primary_key})]
),
"type": "table",
"name": p_name,
}
Expand Down Expand Up @@ -397,10 +412,12 @@ def filter_preset(preset: dict):
self.input_lookup[a]
if (a := k.split(".").pop()) in self.input_lookup
else a
): convert_datetime_string(v)
if a in self.datatype_lookup
and re.search(r"^date.*|time.*$", self.datatype_lookup[a])
else v
): (
convert_datetime_string(v)
if a in self.datatype_lookup
and re.search(r"^date.*|time.*$", self.datatype_lookup[a])
else v
)
for k, v in preset_with_tables_filtered.items()
}

Expand Down Expand Up @@ -483,9 +500,11 @@ def dj_query_route(self):
limit=int(request.args["limit"]) if "limit" in request.args else 1000,
page=int(request.args["page"]) if "page" in request.args else 1,
order=request.args["order"].split(",") if "order" in request.args else None,
restriction=json.loads(b64decode(request.args["restriction"]))
if "restriction" in request.args
else [],
restriction=(
json.loads(b64decode(request.args["restriction"]))
if "restriction" in request.args
else []
),
)

return (
Expand Down Expand Up @@ -522,23 +541,27 @@ def uniques_route(self):
if attribute_info.in_key:
query_attributes["primary"].append(
(
[
dict({"text": str(v), "value": v})
for (v,) in (dj.U(attribute_name) & query).fetch()
]
if True
else None,
(
[
dict({"text": str(v), "value": v})
for (v,) in (dj.U(attribute_name) & query).fetch()
]
if True
else None
),
)
)
else:
query_attributes["secondary"].append(
(
[
dict({"text": str(v), "value": v})
for (v,) in (dj.U(attribute_name) & query).fetch()
]
if True
else None,
(
[
dict({"text": str(v), "value": v})
for (v,) in (dj.U(attribute_name) & query).fetch()
]
if True
else None
),
)
)

Expand Down
8 changes: 5 additions & 3 deletions pharus/dynamic_api_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,11 @@ def {method_name}() -> dict:
component_name=comp_name,
component=json.dumps(comp),
static_config=static_config,
payload="payload=request.get_json()"
if comp["type"].split(":", 1)[0] == "form"
else "",
payload=(
"payload=request.get_json()"
if comp["type"].split(":", 1)[0] == "form"
else ""
),
method_name_type="dj_query_route",
)
)
Expand Down
29 changes: 17 additions & 12 deletions pharus/interface.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Library for interfaces into DataJoint pipelines."""

import datajoint as dj
from datajoint import DataJointError
from datajoint.utils import to_camel_case
Expand Down Expand Up @@ -245,12 +246,14 @@ def _get_attributes(query, include_unique_values=False) -> dict:
attribute_info.nullable,
attribute_info.default,
attribute_info.autoincrement,
[
dict({"text": str(v), "value": v})
for (v,) in (dj.U(attribute_name) & query).fetch()
]
if include_unique_values
else None,
(
[
dict({"text": str(v), "value": v})
for (v,) in (dj.U(attribute_name) & query).fetch()
]
if include_unique_values
else None
),
)
)
else:
Expand All @@ -261,12 +264,14 @@ def _get_attributes(query, include_unique_values=False) -> dict:
attribute_info.nullable,
attribute_info.default,
attribute_info.autoincrement,
[
dict({"text": str(v), "value": v})
for (v,) in (dj.U(attribute_name) & query).fetch()
]
if include_unique_values
else None,
(
[
dict({"text": str(v), "value": v})
for (v,) in (dj.U(attribute_name) & query).fetch()
]
if include_unique_values
else None
),
)
)

Expand Down
3 changes: 2 additions & 1 deletion pharus/server.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Exposed REST API."""

from os import environ
from pathlib import Path
from envyaml import EnvYAML
Expand Down Expand Up @@ -127,7 +128,7 @@ def api_version() -> str:
Content-Type: application/json
{
"version": "0.8.10"
"version": "0.8.11"
}
```
Expand Down
3 changes: 2 additions & 1 deletion pharus/version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
"""Package metadata."""
__version__ = "0.8.10"

__version__ = "0.8.11"

0 comments on commit d2e3c27

Please sign in to comment.