Skip to content

Commit

Permalink
migration bug-fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
mmaelicke committed Jan 8, 2025
1 parent a2007c4 commit 172e4b8
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 53 deletions.
20 changes: 3 additions & 17 deletions metacatalog_api/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,11 @@ def get_db_version(session: Session, schema: str = 'public') -> dict:
return {'db_version': v}


def check_db_version(session: Session, schema: str = 'public') -> bool:
"""Verify that the database version matches the expected version.
Args:
session: A SQLAlchemy session object
Raises:
ValueError: If database version doesn't match DB_VERSION constant
Returns:
bool: True if database version matches
"""
def has_version_mismatch(session: Session, schema: str = 'public') -> bool:
remote_db_version = get_db_version(session, schema=schema)['db_version']
if remote_db_version != DB_VERSION:
raise ValueError(
f"Database version mismatch. Expected {DB_VERSION}, got {remote_db_version}. "
"Please run database migrations to update your schema."
)
return True
return True
return False


def install(session: Session, schema: str = 'public', populate_defaults: bool = True) -> None:
Expand Down
74 changes: 40 additions & 34 deletions metacatalog_api/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,6 @@
from metacatalog_api.db import DB_VERSION


logger = logging.getLogger('uvicorn.error')

# before we initialize the app, we check that the database is installed and up to date
@asynccontextmanager
async def lifespan(app: FastAPI):
# check if the entries table can be found in the database
with core.connect() as session:
if not core.db.check_installed(session):
logger.info("Database not installed, installing...")
core.db.install(session, populate_defaults=True)
logger.info("Database installed.")

# after checking the database, we check the version
with core.connect() as session:
core.db.check_db_version(session)

# now we yield the application
yield

# here we can app tear down code - i.e. a log message

# build the base app
app = FastAPI(lifespan=lifespan)

@app.get('/version')
def get_version(request: Request):
return {
"metacatalog_api": __version__,
"db_version": DB_VERSION,
"hostname": request.url.hostname,
"port": request.url.port,
"root_path": request.url.path
}

class Server(BaseSettings):
model_config = SettingsConfigDict(
cli_parse_args=True,
Expand All @@ -54,6 +20,7 @@ class Server(BaseSettings):
root_path: str = ""
reload: bool = False
app_name: str = "explorer"
autoupgrade: bool = False

@property
def uri_prefix(self):
Expand All @@ -79,9 +46,48 @@ def cli_cmd(self, asgi_app: str):
"""Start the uvicorn server"""
uvicorn.run(asgi_app, host=self.host, port=self.port, root_path=self.root_path, reload=self.reload)

logger = logging.getLogger('uvicorn.error')

# create the server object
server = Server()
logger.info(server.uri_prefix, server.root_path, server.app_name)


# before we initialize the app, we check that the database is installed and up to date
@asynccontextmanager
async def lifespan(app: FastAPI):
# check if the entries table can be found in the database
with core.connect() as session:
if not core.db.check_installed(session):
logger.info("Database not installed, installing...")
core.db.install(session, populate_defaults=True)
logger.info("Database installed.")

# after checking the database, we check the version
with core.connect() as session:
if core.db.has_version_mismatch(session):
if server.autoupgrade:
core.migrate_db()
else:
raise ValueError(f"Database version mismatch. Expected version {core.db.DB_VERSION}. Please run database migrations to update your schema.")

# now we yield the application
yield

# here we can app tear down code - i.e. a log message

# build the base app
app = FastAPI(lifespan=lifespan)

@app.get('/version')
def get_version(request: Request):
return {
"metacatalog_api": __version__,
"db_version": DB_VERSION,
"hostname": request.url.hostname,
"port": request.url.port,
"root_path": request.url.path
}

if __name__ == "__main__":
print("The main server is not meant to be run directly. Check default_server.py for a sample application")
4 changes: 2 additions & 2 deletions metacatalog_api/sql/migrate/migration_3.sql
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
-- change the entryGroup types
ALTER TABLE {schema}.entrygroup_types ALTER COLUMN name type TEXT NOT NULL;
ALTER TABLE {schema}.entrygroup_types ALTER COLUMN description type TEXT NOT NULL;
ALTER TABLE {schema}.entrygroup_types ALTER COLUMN name type TEXT;
ALTER TABLE {schema}.entrygroup_types ALTER COLUMN description type TEXT;

-- add new entry-group types
INSERT INTO {schema}.entrygroup_types VALUES (5, 'Dataset', 'A Dataset collects different self-contained entries (usually of different variables) that belong together. Other than composites, the single entries are self-contained and can be loaded individually.');
Expand Down

0 comments on commit 172e4b8

Please sign in to comment.