Skip to content

Commit

Permalink
add error handling for pre-existing DB objects
Browse files Browse the repository at this point in the history
Add error handling for pre-existing objects in DB; note that we editing how bulk loading works for localities. This appears to have drastically slowed that down (from 5min to 10min), but it allows for error parsing.
  • Loading branch information
cdonnay committed Mar 28, 2024
1 parent 99e462e commit bb970a9
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 19 deletions.
20 changes: 15 additions & 5 deletions gerrydb/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import click

from gerrydb import GerryDB

from gerrydb.exceptions import ResultError

@click.group()
def cli():
Expand All @@ -19,8 +19,13 @@ def namespace(path: str, description: str, public: bool):
"""Creates a namespace."""
db = GerryDB()
with db.context(notes=f'Creating namespace "{path}" from CLI') as ctx:
ctx.namespaces.create(path=path, description=description, public=public)

try:
ctx.namespaces.create(path=path, description=description, public=public)
except ResultError as e:
if "Failed to create namespace" in e.args[0]:
print(f"Failed to create {path} namespace, already exists")
else:
raise e

@cli.command()
@click.argument("path")
Expand All @@ -31,8 +36,13 @@ def geo_layer(path: str, description: str, namespace: str, source_url: Optional[
"""Creates a geographic layer."""
db = GerryDB(namespace=namespace)
with db.context(notes=f'Creating geographic layer "{path}" from CLI') as ctx:
ctx.geo_layers.create(path=path, description=description, source_url=source_url)

try:
ctx.geo_layers.create(path=path, description=description, source_url=source_url)
except ResultError as e:
if "Failed to create geographic layer" in e.args[0]:
print(f"Failed to create {path} layer, already exists")
else:
raise e

if __name__ == "__main__":
cli()
56 changes: 44 additions & 12 deletions gerrydb/repos/locality.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from gerrydb.repos.base import ObjectRepo, err, normalize_path, online, write_context
from gerrydb.schemas import Locality, LocalityCreate, LocalityPatch

from gerrydb.exceptions import ResultError
if TYPE_CHECKING:
from gerrydb.client import GerryDB, WriteContext

Expand Down Expand Up @@ -35,9 +35,9 @@ def get(self, path: str) -> Optional[Locality]:
response.raise_for_status()
return Locality(**response.json())

@err("Failed to create locality")
@write_context
@online
@err("Failed to create locality") # Decorator for handling HTTP request and Pydantic validation errors
@write_context # Decorator for marking operations that require a write context
@online # Decorator for marking online-only operations
def create(
self,
canonical_path: str,
Expand Down Expand Up @@ -66,6 +66,8 @@ def create(
Returns:
The new locality.
"""
# attempts to post the locality (store in webserver)
# url, json
response = self.ctx.client.post(
"/localities/",
json=[
Expand All @@ -78,8 +80,9 @@ def create(
).dict()
],
)
response.raise_for_status()

# checks for errors in the response, if raised, handled by error decorator
response.raise_for_status()
return Locality(**response.json()[0])

@err("Failed to create localities")
Expand All @@ -101,13 +104,42 @@ def create_bulk(
Returns:
The new localities.
"""
response = self.ctx.client.post(
"/localities/",
json=[loc.dict() for loc in locs],
)
response.raise_for_status()

return [Locality(**loc) for loc in response.json()]
loc_list = [-1]*len(locs)
for i, loc in enumerate(locs):
try:
loc_object = self.create(canonical_path=loc.canonical_path,
name=loc.name,
parent_path=loc.parent_path,
default_proj=loc.default_proj,
aliases=loc.aliases,)
loc_list[i] = loc_object
except ResultError as e:
if "Failed to create canonical path to new location(s)." in e.args[0]:
print(f"Failed to create {loc.name}, path already exists")
else:
raise e

return loc_list



# loc_list = [-1]*len(locs)
# for i, loc in enumerate(locs):
# response = self.ctx.client.post(
# "/localities/",
# json=[loc.dict()],
# )
# response.raise_for_status()
# loc_list[i] = Locality(**response.json()[0])
# return(loc_list[i])

# response = self.ctx.client.post(
# "/localities/",
# json=[loc.dict() for loc in locs],
# )
# response.raise_for_status()

# return [Locality(**loc) for loc in response.json()]

@err("Failed to update locality")
@write_context
Expand Down
4 changes: 3 additions & 1 deletion gerrydb/repos/namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
)
from gerrydb.schemas import Namespace, NamespaceCreate


if TYPE_CHECKING:
from gerrydb.client import GerryDB, WriteContext

Expand Down Expand Up @@ -83,8 +84,9 @@ def create(
path=path, public=public, description=description
).dict(),
)
response.raise_for_status()

response.raise_for_status()

return Namespace(**response.json())

def __getitem__(self, path: str) -> Optional[Namespace]:
Expand Down
3 changes: 2 additions & 1 deletion gerrydb/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@

UserEmail = constr(max_length=254)

GerryPath = constr(regex=r"[a-z0-9][a-z0-9-_/]*")
# constr is a constrained string, so this is some path that needs to satisfy this regex
GerryPath = constr(regex=r"[a-z0-9][a-z0-9-_/]*") # must start with lowercase or digit, then followed by any lowercase, digit, hyphen, underscore, slash
NamespacedGerryPath = constr(regex=r"[a-z0-9/][a-z0-9-_/]*")

NATIVE_PROJ = pyproj.CRS("EPSG:4269")
Expand Down

0 comments on commit bb970a9

Please sign in to comment.