mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-12-26 12:15:19 -05:00
Set up alembic migration usage (#954)
* Set up alembic migration usage * Fix import order, add isort as alembic hook * Only run migrations if needed * Include date as part of migration file name for better sorting * Skip initial migrations if tables already exist This eases the transition from a pre-alembic state * Fix deprecation warning in alembic revision * Add alembic test stubs
This commit is contained in:
committed by
GitHub
parent
a897e180ed
commit
fdfb5b1a5e
@@ -18,7 +18,7 @@ ENV = BASE_DIR.joinpath(".env")
|
||||
|
||||
dotenv.load_dotenv(ENV)
|
||||
PRODUCTION = os.getenv("PRODUCTION", "True").lower() in ["true", "1"]
|
||||
TESTING = os.getenv("TESTING", "True").lower() in ["true", "1"]
|
||||
TESTING = os.getenv("TESTING", "False").lower() in ["true", "1"]
|
||||
|
||||
|
||||
def determine_data_dir() -> Path:
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
from pathlib import Path
|
||||
|
||||
from sqlalchemy import engine
|
||||
|
||||
from alembic import command, config, script
|
||||
from alembic.config import Config
|
||||
from alembic.runtime import migration
|
||||
from mealie.core import root_logger
|
||||
from mealie.core.config import get_app_settings
|
||||
from mealie.db.db_setup import create_session, engine
|
||||
from mealie.db.models._model_base import SqlAlchemyBase
|
||||
from mealie.db.db_setup import create_session
|
||||
from mealie.repos.all_repositories import get_repositories
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from mealie.repos.seed.init_users import default_user_init
|
||||
@@ -9,15 +15,11 @@ from mealie.repos.seed.seeders import IngredientFoodsSeeder, IngredientUnitsSeed
|
||||
from mealie.schema.user.user import GroupBase
|
||||
from mealie.services.group_services.group_utils import create_new_group
|
||||
|
||||
PROJECT_DIR = Path(__file__).parent.parent.parent
|
||||
|
||||
logger = root_logger.get_logger("init_db")
|
||||
|
||||
|
||||
def create_all_models():
|
||||
import mealie.db.models._all_models # noqa: F401
|
||||
|
||||
SqlAlchemyBase.metadata.create_all(engine)
|
||||
|
||||
|
||||
def init_db(db: AllRepositories) -> None:
|
||||
# TODO: Port other seed data to use abstract seeder class
|
||||
default_group_init(db)
|
||||
@@ -42,24 +44,33 @@ def default_group_init(db: AllRepositories):
|
||||
create_new_group(db, GroupBase(name=settings.DEFAULT_GROUP))
|
||||
|
||||
|
||||
# Adapted from https://alembic.sqlalchemy.org/en/latest/cookbook.html#test-current-database-revision-is-at-head-s
|
||||
def db_is_at_head(alembic_cfg: config.Config) -> bool:
|
||||
settings = get_app_settings()
|
||||
url = settings.DB_URL
|
||||
connectable = engine.create_engine(url)
|
||||
directory = script.ScriptDirectory.from_config(alembic_cfg)
|
||||
with connectable.begin() as connection:
|
||||
context = migration.MigrationContext.configure(connection)
|
||||
return set(context.get_current_heads()) == set(directory.get_heads())
|
||||
|
||||
|
||||
def main():
|
||||
create_all_models()
|
||||
alembic_cfg = Config(str(PROJECT_DIR / "alembic.ini"))
|
||||
if db_is_at_head(alembic_cfg):
|
||||
logger.info("Migration not needed.")
|
||||
else:
|
||||
logger.info("Migration needed. Performing migration...")
|
||||
command.upgrade(alembic_cfg, "head")
|
||||
|
||||
session = create_session()
|
||||
db = get_repositories(session)
|
||||
|
||||
try:
|
||||
init_user = db.users.get_all()
|
||||
if not init_user:
|
||||
raise Exception("No users found in database")
|
||||
except Exception:
|
||||
init_db(db)
|
||||
return
|
||||
|
||||
init_user = db.users.get_all()
|
||||
if init_user:
|
||||
logger.info("Database Exists")
|
||||
logger.info("Database exists")
|
||||
else:
|
||||
logger.info("Database Doesn't Exists, Initializing...")
|
||||
logger.info("Database contains no users, initializing...")
|
||||
init_db(db)
|
||||
|
||||
|
||||
|
||||
1
mealie/db/migration_types.py
Normal file
1
mealie/db/migration_types.py
Normal file
@@ -0,0 +1 @@
|
||||
from mealie.db.models._model_utils.guid import GUID # noqa: F401
|
||||
@@ -10,10 +10,11 @@ from mealie.db.models._model_utils.guid import GUID
|
||||
|
||||
from .._model_base import BaseMixins, SqlAlchemyBase
|
||||
from .._model_utils import auto_init
|
||||
from ..users import users_to_favorites
|
||||
from ..users.user_to_favorite import users_to_favorites
|
||||
from .api_extras import ApiExtras
|
||||
from .assets import RecipeAsset
|
||||
from .category import recipes_to_categories
|
||||
from .comment import RecipeComment
|
||||
from .ingredient import RecipeIngredient
|
||||
from .instruction import RecipeInstruction
|
||||
from .note import Note
|
||||
@@ -50,7 +51,7 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
|
||||
group_id = sa.Column(GUID, sa.ForeignKey("groups.id"), nullable=False, index=True)
|
||||
group = orm.relationship("Group", back_populates="recipes", foreign_keys=[group_id])
|
||||
|
||||
user_id = sa.Column(GUID, sa.ForeignKey("users.id"), index=True)
|
||||
user_id = sa.Column(GUID, sa.ForeignKey("users.id", use_alter=True), index=True)
|
||||
user = orm.relationship("User", uselist=False, foreign_keys=[user_id])
|
||||
|
||||
meal_entries = orm.relationship("GroupMealPlan", back_populates="recipe", cascade="all, delete-orphan")
|
||||
@@ -93,7 +94,9 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
|
||||
RecipeShareTokenModel, back_populates="recipe", cascade="all, delete, delete-orphan"
|
||||
)
|
||||
|
||||
comments: list = orm.relationship("RecipeComment", back_populates="recipe", cascade="all, delete, delete-orphan")
|
||||
comments: list[RecipeComment] = orm.relationship(
|
||||
"RecipeComment", back_populates="recipe", cascade="all, delete, delete-orphan"
|
||||
)
|
||||
|
||||
# Mealie Specific
|
||||
settings = orm.relationship("RecipeSettings", uselist=False, cascade="all, delete-orphan")
|
||||
|
||||
@@ -5,7 +5,6 @@ from mealie.db.models._model_utils.guid import GUID
|
||||
|
||||
from .._model_base import BaseMixins, SqlAlchemyBase
|
||||
from .._model_utils import auto_init
|
||||
from ..group import Group
|
||||
from .user_to_favorite import users_to_favorites
|
||||
|
||||
|
||||
@@ -74,6 +73,8 @@ class User(SqlAlchemyBase, BaseMixins):
|
||||
settings = get_app_settings()
|
||||
group = settings.DEFAULT_GROUP
|
||||
|
||||
from mealie.db.models.group import Group
|
||||
|
||||
self.group = Group.get_ref(session, group)
|
||||
|
||||
self.favorite_recipes = []
|
||||
@@ -91,6 +92,8 @@ class User(SqlAlchemyBase, BaseMixins):
|
||||
self.full_name = full_name
|
||||
self.email = email
|
||||
|
||||
from mealie.db.models.group import Group
|
||||
|
||||
self.group = Group.get_ref(session, group)
|
||||
|
||||
if self.username is None:
|
||||
|
||||
Reference in New Issue
Block a user