climate_ref.database
#
Database adapter layer
This module provides a database adapter layer that abstracts the database connection and migrations. This allows us to easily switch between different database backends, and to run migrations when the database is loaded.
The Database class is the main entry point for interacting with the database.
It provides a session object that can be used to interact with the database and run queries.
Database
#
Manage the database connection and migrations
The database migrations are optionally run after the connection to the database is established.
Source code in packages/climate-ref/src/climate_ref/database.py
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 | |
alembic_config(config)
#
Get the Alembic configuration object for the database
This includes an open connection with the database engine and the REF configuration.
Returns:
| Type | Description |
|---|---|
Config
|
The Alembic configuration object that can be used with alembic commands |
Source code in packages/climate-ref/src/climate_ref/database.py
close()
#
Close the database connection
This closes the session and disposes of the engine, releasing all connections.
Source code in packages/climate-ref/src/climate_ref/database.py
from_config(config, run_migrations=True, skip_backup=False, *, read_only=False)
staticmethod
#
Create a Database instance from a Config instance
The REF_DATABASE_URL environment variable will take preference,
and override the database URL specified in the config.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
Config
|
The Config instance that includes information about where the database is located |
required |
run_migrations
|
bool
|
If True, run any outstanding database migrations.
Forced to False when |
True
|
skip_backup
|
bool
|
If True, skip creating a backup before running migrations. Useful for read-only commands that don't modify the database. |
False
|
read_only
|
bool
|
If True, open the database in read-only mode and skip migrations. SQLite URLs are rewritten to URI form with |
False
|
Returns:
| Type | Description |
|---|---|
Database
|
A new Database instance |
Source code in packages/climate-ref/src/climate_ref/database.py
get_or_create(model, defaults=None, **kwargs)
#
Get or create an instance of a model
To support concurrent writers, a SAVEPOINT is wrapped around the INSERT operation. This allows for a UNIQUE-constraint violation from a racing transaction to be caught and the row inserted by the winner to be re-fetched instead of crashing. The surrounding transaction (if any) is left intact.
This doesn't commit the outer transaction,
so you will need to call session.commit() after this method
or use a transaction context manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
type[Table]
|
The model to get or create |
required |
defaults
|
dict[str, Any] | None
|
Default values to use when creating a new instance |
None
|
kwargs
|
Any
|
The filter parameters to use when querying for an instance |
{}
|
Returns:
| Type | Description |
|---|---|
tuple[Table, ModelState | None]
|
A tuple containing the instance and enum indicating if the instance was created |
Source code in packages/climate-ref/src/climate_ref/database.py
migrate(config, skip_backup=False)
#
Migrate the database to the latest revision
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
Config
|
REF Configuration This is passed to alembic |
required |
skip_backup
|
bool
|
If True, skip creating a backup before running migrations. Useful for read-only commands that don't modify the database. |
False
|
Source code in packages/climate-ref/src/climate_ref/database.py
migration_status(config)
#
Report the current migration state of the database.
Returns a dict with current (the current revision or None),
head (the latest available revision), and state (a
:class:MigrationState).
This is the canonical way for consumers of the library to check whether
the database schema matches what the installed climate_ref expects.
Prefer it over re-deriving Alembic plumbing in downstream code.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
Config
|
REF Configuration, used to build the Alembic config. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
A dict with keys |
Source code in packages/climate-ref/src/climate_ref/database.py
update_or_create(model, defaults=None, **kwargs)
#
Update an existing instance or create a new one
Safe under concurrent writers: creation goes through :meth:get_or_create,
which wraps the INSERT in a SAVEPOINT so a racing writer's UNIQUE conflict
resolves to fetching the winner's row. Field updates are then applied on top.
Note: last-writer-wins for the update step. If two callers update the same pre-existing row concurrently, the later-committing transaction's values win. This race is inherent to update semantics and is not addressed here.
This doesn't commit the outer transaction,
so you will need to call session.commit() after this method
or use a transaction context manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
type[Table]
|
The model to update or create |
required |
defaults
|
dict[str, Any] | None
|
Default values to use when creating a new instance, or values to update on existing instance |
None
|
kwargs
|
Any
|
The filter parameters to use when querying for an instance |
{}
|
Returns:
| Type | Description |
|---|---|
tuple[Table, ModelState | None]
|
A tuple containing the instance and a state enum indicating if the instance was created or updated |
Source code in packages/climate-ref/src/climate_ref/database.py
MigrationState
#
Bases: Enum
State of the database schema relative to the expected Alembic head.
Source code in packages/climate-ref/src/climate_ref/database.py
ModelState
#
validate_database_url(database_url)
#
Validate a database URL
We support sqlite databases, and we create the directory if it doesn't exist. We may aim to support PostgreSQL databases, but this is currently experimental and untested.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
database_url
|
str
|
The database URL to validate See climate_ref.config.DbConfig.database_url for more information on the format of the URL. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the database scheme is not supported |
Returns:
| Type | Description |
|---|---|
str
|
The validated database URL |