diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 850435e36..4e2ebdfd3 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -28,7 +28,6 @@ services: ports: - 9921:9000 environment: - db_type: sqlite TZ: America/Anchorage # Specify Correct Timezone for Date/Time to line up correctly. volumes: - ./dev/data:/app/dev/data diff --git a/docker-compose.yml b/docker-compose.yml index 457f81576..f96e5c961 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,5 +8,4 @@ services: restart: always ports: - 9090:80 - environment: - db_type: sqlite + diff --git a/docs/docs/getting-started/install.md b/docs/docs/getting-started/install.md index c89b7349f..71d67047a 100644 --- a/docs/docs/getting-started/install.md +++ b/docs/docs/getting-started/install.md @@ -25,7 +25,6 @@ Deployment with the Docker CLI can be done with `docker run` and specify the dat ```shell docker run \ - -e DB_TYPE='sqlite' \ -p 9925:80 \ -v `pwd`:'/app/data/' \ hkotel/mealie:latest @@ -50,7 +49,6 @@ services: ports: - 9925:80 environment: - DB_TYPE: sqlite TZ: America/Anchorage volumes: - ./mealie/data/:/app/data @@ -61,7 +59,7 @@ services: | Variables | Default | Description | | ---------------- | ------------------ | ----------------------------------------------------------------------------------- | -| DB_TYPE | sqlite | The database type to be used. Current Options 'sqlite' | +| DB_URL | None | Leave blank for SQLite | | DEFAULT_GROUP | Home | The default group for users | | DEFAULT_EMAIL | changeme@email.com | The default username for the superuser | | DEFAULT_PASSWORD | MyPassword | The default password for the superuser | diff --git a/mealie/core/config.py b/mealie/core/config.py index bdae8d392..3c2826f79 100644 --- a/mealie/core/config.py +++ b/mealie/core/config.py @@ -1,10 +1,10 @@ import os import secrets from pathlib import Path -from typing import Optional, Union +from typing import Optional import dotenv -from pydantic import BaseSettings, Field, validator +from pydantic import BaseSettings, Field APP_VERSION = "v0.5.0beta" DB_VERSION = "v0.5.0" @@ -57,7 +57,6 @@ class AppDirectories: self.CHOWDOWN_DIR: Path = self.MIGRATION_DIR.joinpath("chowdown") self.TEMPLATE_DIR: Path = data_dir.joinpath("templates") self.USER_DIR: Path = data_dir.joinpath("users") - self.SQLITE_DIR: Path = data_dir.joinpath("db") self.RECIPE_DATA_DIR: Path = data_dir.joinpath("recipes") self.TEMP_DIR: Path = data_dir.joinpath(".temp") @@ -70,7 +69,6 @@ class AppDirectories: self.DEBUG_DIR, self.MIGRATION_DIR, self.TEMPLATE_DIR, - self.SQLITE_DIR, self.NEXTCLOUD_DIR, self.CHOWDOWN_DIR, self.RECIPE_DATA_DIR, @@ -84,6 +82,12 @@ class AppDirectories: app_dirs = AppDirectories(CWD, DATA_DIR) +def determine_sqlite_path() -> str: + global app_dirs + db_path = app_dirs.DATA_DIR.joinpath(f"mealie_{DB_VERSION}.db") # ! Temporary Until Alembic + return "sqlite:///" + str(db_path.absolute()) + + class AppSettings(BaseSettings): global DATA_DIR PRODUCTION: bool = Field(True, env="PRODUCTION") @@ -100,21 +104,7 @@ class AppSettings(BaseSettings): return "/redoc" if self.API_DOCS else None SECRET: str = determine_secrets(DATA_DIR, PRODUCTION) - DATABASE_TYPE: str = Field("sqlite", env="DB_TYPE") - - @validator("DATABASE_TYPE", pre=True) - def validate_db_type(cls, v: str) -> Optional[str]: - if v != "sqlite": - raise ValueError("Unable to determine database type. Acceptible options are 'sqlite'") - else: - return v - - # Used to Set SQLite File Version - SQLITE_FILE: Optional[Union[str, Path]] - - @validator("SQLITE_FILE", pre=True) - def identify_sqlite_file(cls, v: str) -> Optional[str]: - return app_dirs.SQLITE_DIR.joinpath(f"mealie_{DB_VERSION}.sqlite") + DB_URL: str = Field(default_factory=determine_sqlite_path, env="DB_URL") DEFAULT_GROUP: str = "Home" DEFAULT_EMAIL: str = "changeme@email.com" diff --git a/mealie/db/db_setup.py b/mealie/db/db_setup.py index c9c5d99cd..ecca4a4b6 100644 --- a/mealie/db/db_setup.py +++ b/mealie/db/db_setup.py @@ -1,12 +1,13 @@ -from mealie.core.config import settings -from sqlalchemy.orm.session import Session +from pathlib import Path +from mealie.core.config import settings from mealie.db.models.db_session import sql_global_init +from sqlalchemy.orm.session import Session sql_exists = True -sql_exists = settings.SQLITE_FILE.is_file() -SessionLocal = sql_global_init(settings.SQLITE_FILE) +sql_exists = Path(settings.DB_URL).is_file() +SessionLocal = sql_global_init(settings.DB_URL) def create_session() -> Session: diff --git a/mealie/db/models/db_session.py b/mealie/db/models/db_session.py index 78dcbc71b..b5ac2ef36 100644 --- a/mealie/db/models/db_session.py +++ b/mealie/db/models/db_session.py @@ -1,20 +1,14 @@ -from pathlib import Path - import sqlalchemy as sa from mealie.db.models.model_base import SqlAlchemyBase from sqlalchemy.orm import sessionmaker -def sql_global_init(db_file: Path, check_thread=False): +def sql_global_init(db_url: str): + connect_args = {} + if "sqlite" in db_url: + connect_args["check_same_thread"] = False - SQLALCHEMY_DATABASE_URL = "sqlite:///" + str(db_file.absolute()) - # SQLALCHEMY_DATABASE_URL = "postgresql://user:password@postgresserver/db" - - engine = sa.create_engine( - SQLALCHEMY_DATABASE_URL, - echo=False, - connect_args={"check_same_thread": check_thread}, - ) + engine = sa.create_engine(db_url, echo=False, connect_args=connect_args) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) diff --git a/mealie/db/models/recipe/category.py b/mealie/db/models/recipe/category.py index bacb50fc9..39d620915 100644 --- a/mealie/db/models/recipe/category.py +++ b/mealie/db/models/recipe/category.py @@ -8,7 +8,7 @@ from sqlalchemy.orm import validates logger = root_logger.get_logger() site_settings2categories = sa.Table( - "site_settings2categoories", + "site_settings2categories", SqlAlchemyBase.metadata, sa.Column("sidebar_id", sa.Integer, sa.ForeignKey("site_settings.id")), sa.Column("category_id", sa.String, sa.ForeignKey("categories.id")), diff --git a/mealie/routes/debug_routes.py b/mealie/routes/debug_routes.py index 500ee742e..3e5d6c4b8 100644 --- a/mealie/routes/debug_routes.py +++ b/mealie/routes/debug_routes.py @@ -18,8 +18,7 @@ async def get_debug_info(current_user=Depends(get_current_user)): demo_status=settings.IS_DEMO, api_port=settings.API_PORT, api_docs=settings.API_DOCS, - db_type=settings.DATABASE_TYPE, - sqlite_file=settings.SQLITE_FILE, + db_url=settings.DB_URL, default_group=settings.DEFAULT_GROUP, ) diff --git a/mealie/schema/debug.py b/mealie/schema/debug.py index 0348af14b..d00c17719 100644 --- a/mealie/schema/debug.py +++ b/mealie/schema/debug.py @@ -11,6 +11,5 @@ class AppInfo(CamelModel): class DebugInfo(AppInfo): api_port: int api_docs: bool - db_type: str - sqlite_file: Path + db_url: Path default_group: str diff --git a/template.env b/template.env index 0ec7acf1c..322f7cf8b 100644 --- a/template.env +++ b/template.env @@ -14,8 +14,8 @@ API_PORT=9000 # Exposes /docs and /redoc on the server API_DOCS=True -# Sets the Database type to use. Currently the only supported options is 'sqlite' -DB_TYPE=sqlite +# Sets the Database type to use. +# DB_URL # Sets the token expiration time in hours. TOKEN_TIME=24 diff --git a/tests/conftest.py b/tests/conftest.py index f12b327f6..37d93781a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,10 +1,10 @@ from mealie.core.config import app_dirs, settings # ! I don't like it either! -SQLITE_FILE = app_dirs.SQLITE_DIR.joinpath("test.db") -SQLITE_FILE.unlink(missing_ok=True) +DB_URL = app_dirs.DATA_DIR.joinpath("test.db") +DB_URL.unlink(missing_ok=True) -settings.SQLITE_FILE = SQLITE_FILE +settings.DB_URL = DB_URL import json @@ -19,7 +19,7 @@ from tests.app_routes import AppRoutes from tests.test_config import TEST_DATA from tests.utils.recipe_data import build_recipe_store, get_raw_no_image, get_raw_recipe -TestSessionLocal = sql_global_init(SQLITE_FILE, check_thread=False) +TestSessionLocal = sql_global_init(DB_URL) init_db(TestSessionLocal()) @@ -38,7 +38,7 @@ def api_client(): yield TestClient(app) - SQLITE_FILE.unlink() + DB_URL.unlink() @fixture(scope="session") diff --git a/tests/data/migrations/chowdown/chowdown-gh-pages.zip b/tests/data/migrations/chowdown/chowdown-gh-pages.zip deleted file mode 100644 index bd90e08d4..000000000 Binary files a/tests/data/migrations/chowdown/chowdown-gh-pages.zip and /dev/null differ diff --git a/tests/data/migrations/nextcloud/new_nextcloud.zip b/tests/data/migrations/nextcloud/new_nextcloud.zip deleted file mode 100644 index a420370ff..000000000 Binary files a/tests/data/migrations/nextcloud/new_nextcloud.zip and /dev/null differ diff --git a/tests/unit_tests/test_config.py b/tests/unit_tests/test_config.py index 895420a34..a86abaae5 100644 --- a/tests/unit_tests/test_config.py +++ b/tests/unit_tests/test_config.py @@ -1,6 +1,5 @@ from pathlib import Path -import pytest from mealie.core.config import CWD, DATA_DIR, AppDirectories, AppSettings, determine_data_dir, determine_secrets @@ -9,14 +8,12 @@ def test_default_settings(monkeypatch): monkeypatch.delenv("DEFAULT_PASSWORD", raising=False) monkeypatch.delenv("API_PORT", raising=False) monkeypatch.delenv("API_DOCS", raising=False) - monkeypatch.delenv("DB_TYPE", raising=False) monkeypatch.delenv("IS_DEMO", raising=False) app_settings = AppSettings() assert app_settings.DEFAULT_GROUP == "Home" assert app_settings.DEFAULT_PASSWORD == "MyPassword" - assert app_settings.DATABASE_TYPE == "sqlite" assert app_settings.API_PORT == 9000 assert app_settings.API_DOCS is True assert app_settings.IS_DEMO is False @@ -42,13 +39,6 @@ def test_non_default_settings(monkeypatch): assert app_settings.DOCS_URL is None -def test_unknown_database(monkeypatch): - monkeypatch.setenv("DB_TYPE", "nonsense") - - with pytest.raises(ValueError, match="Unable to determine database type. Acceptible options are 'sqlite'"): - AppSettings() - - def test_secret_generation(tmp_path): app_dirs = AppDirectories(CWD, DATA_DIR) assert determine_secrets(app_dirs.DATA_DIR, False) == "shh-secret-test-key"