add support for setting db_url

This commit is contained in:
hay-kot 2021-04-29 22:09:27 -08:00
commit e96db98166
14 changed files with 31 additions and 62 deletions

View file

@ -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

View file

@ -8,5 +8,4 @@ services:
restart: always
ports:
- 9090:80
environment:
db_type: sqlite

View file

@ -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 |

View file

@ -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"

View file

@ -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:

View file

@ -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)

View file

@ -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")),

View file

@ -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,
)

View file

@ -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

View file

@ -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

View file

@ -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")

View file

@ -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"