Migrations¶
migrations
¶
Alembic integration behind a project's env.py: URL resolution, import_models, run,
revision generation (process_revision_directives). Extra spltz-viur-models[migrations].
target_metadata
¶
import_models
¶
Import each package and its non-private submodules (one level) to fill SQLModel.metadata.
Returns the imported module names.
Source code in src/viur/models/migrations.py
resolve_url
¶
resolve_url(config: Config | None = None, *, x_args: dict | None = None, fallback_url: str | None = None) -> str
Database URL for this run, most explicit first: -x url=… (x_args),
$VIUR_MODELS_DSN, the configured engine, the conf.models preset, fallback_url,
sqlalchemy.url from alembic.ini. -x db=<name> selects a non-default database
(engine or conf.models.databases entry only). RuntimeError when none applies.
Source code in src/viur/models/migrations.py
include_object
¶
Autogenerate filter: everything but alembic_version. Wrap it to exclude foreign tables.
Source code in src/viur/models/migrations.py
include_object_for
¶
include_object restricted to the tables of database (db.tables_for).
Source code in src/viur/models/migrations.py
render_item
¶
Render a TypeDecorator as its impl type (RecordJSON cannot round-trip);
SQLModel's decorators and dialect-specific impls are left to Alembic.
Source code in src/viur/models/migrations.py
run_offline
¶
--sql mode.
Source code in src/viur/models/migrations.py
run_online
¶
Connect and run the migrations in one transaction.
Source code in src/viur/models/migrations.py
run
¶
env.py entry point: resolve the URL (-x db=<name> picks the database), dispatch
offline/online; overrides go to context.configure. Returns the URL.
Source code in src/viur/models/migrations.py
process_revision_directives
¶
Alembic hook: correct the DDL diff for bone-level transitions, write the structure snapshot.
Source code in src/viur/models/migrations.py
scaffold
¶
Alembic scaffold generator (alembic.ini + migrations/); never overwrites.
generate
¶
generate(root: str | PathLike, *, app_dir: str | PathLike | None = None, models_package: str = 'models', settings_module: str = 'models_db') -> list[str]
Write the missing scaffold files into root.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app_dir
|
str | PathLike | None
|
Distribution folder for |
None
|
models_package
|
str
|
Package |
'models'
|
settings_module
|
str
|
Module providing the |
'models_db'
|
Returns:
| Type | Description |
|---|---|
list[str]
|
Created paths relative to |
Source code in src/viur/models/scaffold.py
is_complete
¶
schema
¶
Structure snapshots and bone-level diffing; snapshots live in
<script_location>/structures/<revision>.json.
Transition
dataclass
¶
One bone-level change.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kind
|
str
|
See |
required |
old
|
dict | None
|
Previous bone entry ( |
None
|
new
|
dict | None
|
Current bone entry ( |
None
|
detail
|
dict
|
Facts the operation needs (link table, columns, languages, …). |
dict()
|
Source code in src/viur/models/schema.py
describe
¶
Snapshot entry of one model; resolve_refs=False (no skeleton registry in a shell),
bypasses the structure cache.
Source code in src/viur/models/schema.py
snapshot
¶
Describe every imported Model table (migrations.import_models).
snapshot_dir
¶
prune
¶
Delete snapshots of revisions that no longer exist. Returns the removed ids.
Source code in src/viur/models/schema.py
load
¶
One snapshot; {} for an unknown/missing revision (diff then reports only additions).
Source code in src/viur/models/schema.py
diff
¶
diff(old: dict, new: dict) -> list[Transition]
Bone-level transitions between two snapshots, by table then field.
Kinds: field_added/field_removed, multiple_collapsed/multiple_expanded
(link table ↔ FK column), languages_reduced/languages_expanded, type_changed
(detail["from"]/["to"]), select_values_changed, precision_changed,
using_field_added/using_field_removed (link model payload).
Source code in src/viur/models/schema.py
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 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 | |
migrate
¶
Alembic operations for bone-level data migrations; row-wise coercions per viur-core's rules.
ReduceLanguagesOp
¶
Bases: _ViURMigrateOp
Language[X] → plain field (pick_language).
Source code in src/viur/models/migrate.py
ExpandLanguagesOp
¶
Bases: _ViURMigrateOp
Plain field → Language[X] (wrap_language).
Source code in src/viur/models/migrate.py
CoerceNumericOp
¶
Bases: _ViURMigrateOp
Numeric precision change (coerce_number).
Source code in src/viur/models/migrate.py
CoerceTextOp
¶
Bases: _ViURMigrateOp
str ↔ Text and other string retypes (coerce_text); Alembic does not detect a
dropped max_length.
Source code in src/viur/models/migrate.py
CoerceBoolOp
¶
Bases: _ViURMigrateOp
Anything → bool (coerce_bool).
Source code in src/viur/models/migrate.py
RemapValuesOp
¶
Bases: _ViURMigrateOp
Explicit value mapping (bool → select); a mapping still holding Ellipsis refuses to run.
Source code in src/viur/models/migrate.py
FillColumnOp
¶
Bases: _ViURMigrateOp
Fill NULLs with value, then optionally NOT NULL — the new-required-field case.
Source code in src/viur/models/migrate.py
AddEnumValuesOp
¶
Bases: _ViURMigrateOp
ALTER TYPE … ADD VALUE IF NOT EXISTS for every label (Postgres only, no-op elsewhere).
Removing a label is not covered.
Source code in src/viur/models/migrate.py
CollapseMultipleOp
¶
Bases: _ViURMigrateOp
Multiple relation → single FK column (pick_from_multiple); the link table is dropped
after the copy. target_type: the FK column's type (default Integer; BigQueryModel
needs a string type).
Source code in src/viur/models/migrate.py
ExpandMultipleOp
¶
Bases: _ViURMigrateOp
Single FK column → link table, one row per value. payload_defaults fills NOT NULL
payload columns; an Ellipsis stub refuses to run (as RemapValuesOp), nullable
payload stays NULL.
Source code in src/viur/models/migrate.py
pick_from_multiple
¶
BaseBone.unserialize rule loadVal[0]; keep="last" takes the last.
pick_language
¶
Multilingual dict → one value (BaseBone.unserialize): keep if present (even
None), else the first non-None value; a list picks its first item.
Source code in src/viur/models/migrate.py
wrap_language
¶
Scalar → {lang: value} under languages[0] (BaseBone.unserialize), the rest None.
Source code in src/viur/models/migrate.py
coerce_number
¶
NumericBone._convert_to_numeric: precision > 0 rounds, 0 truncates toward zero.
Source code in src/viur/models/migrate.py
coerce_text
¶
StringBone.type_coerce_single_value: stringify, dates ISO, never truncate.
Source code in src/viur/models/migrate.py
coerce_bool
¶
ensure_schema_type
¶
Create a dialect-level type (Postgres Enum) before its column; no-op elsewhere.
Returns whether one was created.
Source code in src/viur/models/migrate.py
transform_column
¶
transform_column(operations: Any, table: str, column: str, *, new_type: Any, transform: Callable[[Any], Any], pk: str = 'id', nullable: bool = True) -> int
Retype column through a temporary column: add, copy through transform, drop,
rename, constrain — alike on SQLite (batch) and Postgres. Returns rows written.