Core Database Functions#
This page documents the core database connection and initialization API. These are the entry points for working with ops-db programmatically.
Configuration#
Database connection parameters are managed via Dynaconf settings. The configuration file is located at ccat_ops_db/config/settings.toml.
Default settings:
[default]
database_type = "sqlite"
database_sqlite_database = "/tmp/dev_ccat_ops_db.sqlite"
database_postgresql_database = "ccat_ops_db"
database_postgresql_user = "ccat"
database_postgresql_password = "pw4ccat"
database_postgresql_host = "localhost"
database_postgresql_port = "5432"
Environment-specific settings (e.g., [production], [development]) override
defaults.
Environment variables with prefix CCAT_OPS_DB_ can override any setting:
export CCAT_OPS_DB_DATABASE_TYPE=postgresql
export CCAT_OPS_DB_DATABASE_POSTGRESQL_HOST=db.prod.example.com
The active environment is set via ENV_FOR_DYNACONF environment variable:
export ENV_FOR_DYNACONF=production
Database Initialization#
This function is a helper function for development and staging purposes. It fills the database with the starting seed that we used for production it will generate a representative starting state with defined obs_units, sources, instruments, and the like. A seeded database can be immediately used to simulate observing and data transfer as well as data reduction and archive transfer in our development and staging environments.
- ccat_ops_db.init_ccat_ops_db(database_type: str | None = None, database: str | None = None, drop: bool = False, null_pool: bool = False, host: str | None = None, port: str | None = None, user: str | None = None, password: str | None = None, db_name: str | None = None) Tuple[scoped_session, Engine][source]#
Initialize a database connection based on the supplied configuration.
Parameters:#
- database_type: str, optional
Can be ‘sqlite’, ‘mysql’, or ‘postgresql’. Defaults to config setting.
- database: str, optional
URL string to connect to the database. Defaults to config setting.
- drop: bool, default False
If True, drops all tables before creating them.
- null_pool: bool, default False
If True, uses NullPool instead of the default connection pool.
- host: str, optional
Database host override.
- port: str, optional
Database port override.
- user: str, optional
Database user override.
- password: str, optional
Database password override.
- db_name: str, optional
Database name override.
Returns:#
- Tuple[scoped_session, Engine]
A tuple containing the database session and engine.
Usage Example:
from ccat_ops_db import init_ccat_ops_db
# Initialize with default settings (from environment)
session, engine = init_ccat_ops_db()
# Initialize with specific database
session, engine = init_ccat_ops_db(
database_type="postgresql",
host="db.example.com",
port="5432",
user="myuser",
password="mypass",
db_name="ops_db"
)
# Initialize and drop existing tables (for testing)
session, engine = init_ccat_ops_db(drop=True)
# Use NullPool for short-lived connections
session, engine = init_ccat_ops_db(null_pool=True)
Database URL Construction#
- ccat_ops_db.get_database_url(database_type: str, database: str | None = None, host: str | None = None, port: str | None = None, user: str | None = None, password: str | None = None, db_name: str | None = None, async_driver: bool = False) str[source]#
Generate database URL based on type and configuration.
- Parameters:
database_type – Type of database (‘sqlite’, ‘mysql’, ‘postgresql’)
database – Optional database URL override
host – Optional host override
port – Optional port override
user – Optional user override
password – Optional password override
db_name – Optional database name override
async_driver – Whether to use async driver (e.g., asyncpg for PostgreSQL)
Usage Example:
from ccat_ops_db import get_database_url
# PostgreSQL URL
url = get_database_url(
database_type="postgresql",
host="localhost",
port="5432",
user="ccat",
password="secret",
db_name="ccat_ops_db"
)
# Returns: postgresql://ccat:secret@localhost:5432/ccat_ops_db
# Async PostgreSQL URL
url = get_database_url(
database_type="postgresql",
host="localhost",
db_name="ccat_ops_db",
async_driver=True
)
# Returns: postgresql+asyncpg://...
# SQLite URL
url = get_database_url(
database_type="sqlite",
database="/tmp/test.db"
)
# Returns: sqlite:////tmp/test.db
Connection Pooling#
By default, SQLAlchemy uses connection pooling. For short-lived scripts or testing, you may want to disable pooling:
session, engine = init_ccat_ops_db(null_pool=True)
This uses NullPool, which creates a new connection for each operation and closes it
immediately.
For long-running applications (like the API server), use the default pooling behavior.
Working with the Session#
The returned session is a SQLAlchemy scoped_session:
from ccat_ops_db import init_ccat_ops_db
from ccat_ops_db.models import Observatory
session, engine = init_ccat_ops_db()
# Query
obs = session.query(Observatory).filter_by(name="CCAT").first()
# Add
new_obs = Observatory(name="Test", description="Test observatory")
session.add(new_obs)
session.commit()
# Close when done
session.close()
For context manager usage:
from contextlib import contextmanager
@contextmanager
def get_db_session():
session, engine = init_ccat_ops_db()
try:
yield session
session.commit()
except:
session.rollback()
raise
finally:
session.close()
with get_db_session() as session:
# Your database operations
pass