Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ALTER TABLE maps.sources ADD COLUMN IF NOT EXISTS raster_url text;
ALTER TABLE maps.sources ADD COLUMN IF NOT EXISTS scale_denominator integer;
ALTER TABLE maps.sources ADD COLUMN IF NOT EXISTS is_finalized boolean DEFAULT false;
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"""
Macrostrat line orientation management
"""

from macrostrat.core.migrations import Migration, has_columns
from macrostrat.database import Database

_has_column = has_columns("maps", "sources", "lines_oriented")


class MapsLinesOriented(Migration):
name = "maps-lines-oriented"
subsystem = "maps"
description = "Create a flag for line orientations in maps.sources table."

depends_on = ["baseline"]

postconditions = [_has_column]

def apply(self, db: Database):
db.run_sql("ALTER TABLE maps.sources ADD COLUMN lines_oriented boolean")


# Legacy maps with consistently-oriented linework that needs to be reversed
valid_maps = [229, 210, 74, 75, 40, 205, 154]

# Legacy maps with consistently-oriented linework that does not need to be reversed
reversed_maps = [4]
# Note: we have flipped the logic here relative to how we did this in the original iteration
# of the system, to aloign with FGDC recommendations (we think)


def matching_sources(
db: Database, sources: list[int], condition: str = "true"
) -> list[int]:
return list(
db.run_query(
f"SELECT source_id FROM maps.sources WHERE source_id = ANY(:sources) AND {condition}",
dict(sources=sources),
).scalars()
)


def some_maps_are_unoriented(db: Database) -> bool:
if not _has_column(db):
return False
ids = matching_sources(
db, valid_maps + reversed_maps, "NOT coalesce(lines_oriented, false)"
)
return len(ids) > 0


def all_maps_are_oriented(db: Database) -> bool:
if not _has_column(db):
return False
_all_maps = valid_maps + reversed_maps
ids = matching_sources(db, _all_maps, "coalesce(lines_oriented, false)")
return len(ids) == len(_all_maps)


class MapsLinesOrientedDataMigration(Migration):
name = "maps-lines-oriented-data"
subsystem = "maps"
depends_on = ["maps-lines-oriented"]

destructive = True

preconditions = [some_maps_are_unoriented]
postconditions = [all_maps_are_oriented]

def apply(self, db: Database):
# Get the maps that aren't oriented but appear in our list of maps to migrate
all_maps = valid_maps + reversed_maps
unoriented_maps = matching_sources(
db, all_maps, "NOT coalesce(lines_oriented, false)"
)
for source_id in unoriented_maps:
if source_id in reversed_maps:
db.run_sql(
"UPDATE maps.lines SET geom = ST_Reverse(geom) WHERE source_id = :source_id",
dict(source_id=source_id),
)
db.run_sql(
"UPDATE maps.sources SET lines_oriented = true WHERE source_id = :source_id",
dict(source_id=source_id),
)
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
ALTER TABLE maps.sources ADD COLUMN IF NOT EXISTS raster_url text;
ALTER TABLE maps.sources ADD COLUMN IF NOT EXISTS scale_denominator integer;
ALTER TABLE maps.sources ADD COLUMN IF NOT EXISTS is_finalized boolean DEFAULT false;

DROP VIEW IF EXISTS macrostrat_api.sources_metadata CASCADE;
DROP VIEW IF EXISTS maps.sources_metadata CASCADE;
DROP VIEW IF EXISTS macrostrat_api.sources CASCADE;
DROP VIEW IF EXISTS macrostrat_api.sources_metadata;
DROP VIEW IF EXISTS maps.sources_metadata;
DROP VIEW IF EXISTS macrostrat_api.sources;

CREATE OR REPLACE VIEW maps.sources_metadata AS
SELECT
Expand All @@ -26,7 +22,8 @@ SELECT
status_code,
raster_url,
scale_denominator,
is_finalized
is_finalized,
lines_oriented
FROM maps.sources AS s
ORDER BY source_id DESC;

Expand Down Expand Up @@ -89,5 +86,6 @@ SELECT
s.raster_url,
s.web_geom envelope,
s.is_finalized,
s.scale_denominator
s.scale_denominator,
s.lines_oriented
FROM maps.sources s;
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from macrostrat.core.migrations import Migration, has_columns, view_exists


class MapsSourcesAPIMigration(Migration):
name = "maps-sources-api"
subsystem = "maps"
description = """
Create views for sources_metadata and ingest_process in the maps and macrostrat_api schemas
"""

depends_on = ["baseline"]

postconditions = [
view_exists(
"macrostrat_api", "sources_metadata", "sources_ingestion", "sources"
),
has_columns(
"macrostrat_api",
"sources",
"is_finalized",
"scale_denominator",
"lines_oriented",
allow_view=True,
),
]
8 changes: 6 additions & 2 deletions core/macrostrat/core/migrations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,15 @@ def custom_type_exists(schema: str, *type_names: str) -> DbEvaluator:
return lambda db: all(db.inspector.has_type(t, schema=schema) for t in type_names)


def has_columns(schema: str, table: str, *fields: str) -> DbEvaluator:
def has_columns(schema: str, table: str, *fields: str, allow_view=False) -> DbEvaluator:
"""Return a function that evaluates to true when every given field in the given table exists"""

def _has_fields(db: Database) -> bool:
if not db.inspector.has_table(table, schema=schema):
_has_table = db.inspector.has_table(table, schema=schema)
if not _has_table and not allow_view:
return False
_has_view = table in db.inspector.get_view_names(schema)
if not _has_table and not _has_view:
return False
columns = db.inspector.get_columns(table, schema=schema)
col_names = [c["name"] for c in columns]
Expand Down