Coverage for opt/mealie/lib/python3.12/site-packages/mealie/alembic/env.py: 52%
34 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-11-25 15:32 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-11-25 15:32 +0000
1from typing import Any 1a
3import sqlalchemy as sa 1a
4from alembic import context 1a
6import mealie.db.models._all_models # noqa: F401 1a
7from mealie.core.config import get_app_settings 1a
8from mealie.db.models._model_base import SqlAlchemyBase 1a
10# this is the Alembic Config object, which provides
11# access to the values within the .ini file in use.
12config = context.config 1a
14# add your model's MetaData object here
15# for 'autogenerate' support
16# from myapp import mymodel
17# target_metadata = mymodel.Base.metadata
18target_metadata = SqlAlchemyBase.metadata 1a
20# other values from the config, defined by the needs of env.py,
21# can be acquired:
22# my_important_option = config.get_main_option("my_important_option")
23# ... etc.
25# Set DB url from config
26settings = get_app_settings() 1a
28if not settings.DB_URL: 28 ↛ 29line 28 didn't jump to line 29 because the condition on line 28 was never true1a
29 raise Exception("DB URL not set in config")
31config.set_main_option("sqlalchemy.url", settings.DB_URL.replace("%", "%%")) 1a
34def include_object(object: Any, name: str, type_: str, reflected: bool, compare_to: Any): 1a
35 # skip dropping food/unit unique constraints; they are defined manually so alembic doesn't see them
36 # see: revision dded3119c1fe
37 if type_ == "unique_constraint" and name == "ingredient_foods_name_group_id_key" and compare_to is None:
38 return False
39 if type_ == "unique_constraint" and name == "ingredient_units_name_group_id_key" and compare_to is None:
40 return False
42 # skip changing the quantity column in recipes_ingredients; it's a float on postgres, but an integer on sqlite
43 # see: revision 263dd6707191
44 if (
45 type_ == "column"
46 and name == "quantity"
47 and object.table.name == "recipes_ingredients"
48 and hasattr(compare_to, "type")
49 and isinstance(compare_to.type, sa.Integer)
50 ):
51 return False
53 return True
56def run_migrations_offline(): 1a
57 """Run migrations in 'offline' mode.
59 This configures the context with just a URL
60 and not an Engine, though an Engine is acceptable
61 here as well. By skipping the Engine creation
62 we don't even need a DBAPI to be available.
64 Calls to context.execute() here emit the given string to the
65 script output.
67 """
68 url = config.get_main_option("sqlalchemy.url")
69 context.configure(
70 url=url,
71 target_metadata=target_metadata,
72 literal_binds=True,
73 dialect_opts={"paramstyle": "named"},
74 )
76 with context.begin_transaction():
77 context.run_migrations()
80def run_migrations_online(): 1a
81 """Run migrations in 'online' mode.
83 In this scenario we need to create an Engine
84 and associate a connection with the context.
86 """
87 connectable = sa.engine_from_config( 1a
88 config.get_section(config.config_ini_section),
89 prefix="sqlalchemy.",
90 poolclass=sa.pool.NullPool,
91 )
93 with connectable.connect() as connection: 1a
94 context.configure( 1a
95 connection=connection,
96 target_metadata=target_metadata,
97 user_module_prefix="mealie.db.migration_types.",
98 render_as_batch=True,
99 include_object=include_object,
100 )
102 with context.begin_transaction(): 1a
103 context.run_migrations() 1a
106if context.is_offline_mode(): 106 ↛ 107line 106 didn't jump to line 107 because the condition on line 106 was never true1a
107 run_migrations_offline()
108else:
109 run_migrations_online() 1a