mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-22 14:33:33 -07:00
Add alembic
This commit is contained in:
parent
7559c66127
commit
3022cc20ec
19 changed files with 2712 additions and 2227 deletions
89
alembic.ini
Normal file
89
alembic.ini
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
# A generic, single database configuration.
|
||||||
|
|
||||||
|
[alembic]
|
||||||
|
# path to migration scripts
|
||||||
|
script_location = alembic
|
||||||
|
|
||||||
|
# template used to generate migration files
|
||||||
|
# file_template = %%(rev)s_%%(slug)s
|
||||||
|
|
||||||
|
# sys.path path, will be prepended to sys.path if present.
|
||||||
|
# defaults to the current working directory.
|
||||||
|
prepend_sys_path = .
|
||||||
|
|
||||||
|
# timezone to use when rendering the date
|
||||||
|
# within the migration file as well as the filename.
|
||||||
|
# string value is passed to dateutil.tz.gettz()
|
||||||
|
# leave blank for localtime
|
||||||
|
# timezone =
|
||||||
|
|
||||||
|
# max length of characters to apply to the
|
||||||
|
# "slug" field
|
||||||
|
# truncate_slug_length = 40
|
||||||
|
|
||||||
|
# set to 'true' to run the environment during
|
||||||
|
# the 'revision' command, regardless of autogenerate
|
||||||
|
# revision_environment = false
|
||||||
|
|
||||||
|
# set to 'true' to allow .pyc and .pyo files without
|
||||||
|
# a source .py file to be detected as revisions in the
|
||||||
|
# versions/ directory
|
||||||
|
# sourceless = false
|
||||||
|
|
||||||
|
# version location specification; this defaults
|
||||||
|
# to alembic/versions. When using multiple version
|
||||||
|
# directories, initial revisions must be specified with --version-path
|
||||||
|
# version_locations = %(here)s/bar %(here)s/bat alembic/versions
|
||||||
|
|
||||||
|
# the output encoding used when revision files
|
||||||
|
# are written from script.py.mako
|
||||||
|
# output_encoding = utf-8
|
||||||
|
|
||||||
|
sqlalchemy.url = sqlite:///mealie.db
|
||||||
|
|
||||||
|
|
||||||
|
[post_write_hooks]
|
||||||
|
# post_write_hooks defines scripts or Python functions that are run
|
||||||
|
# on newly generated revision scripts. See the documentation for further
|
||||||
|
# detail and examples
|
||||||
|
|
||||||
|
# format using "black" - use the console_scripts runner, against the "black" entrypoint
|
||||||
|
# hooks=black
|
||||||
|
# black.type=console_scripts
|
||||||
|
# black.entrypoint=black
|
||||||
|
# black.options=-l 79
|
||||||
|
|
||||||
|
# Logging configuration
|
||||||
|
[loggers]
|
||||||
|
keys = root,sqlalchemy,alembic
|
||||||
|
|
||||||
|
[handlers]
|
||||||
|
keys = console
|
||||||
|
|
||||||
|
[formatters]
|
||||||
|
keys = generic
|
||||||
|
|
||||||
|
[logger_root]
|
||||||
|
level = WARN
|
||||||
|
handlers = console
|
||||||
|
qualname =
|
||||||
|
|
||||||
|
[logger_sqlalchemy]
|
||||||
|
level = WARN
|
||||||
|
handlers =
|
||||||
|
qualname = sqlalchemy.engine
|
||||||
|
|
||||||
|
[logger_alembic]
|
||||||
|
level = INFO
|
||||||
|
handlers =
|
||||||
|
qualname = alembic
|
||||||
|
|
||||||
|
[handler_console]
|
||||||
|
class = StreamHandler
|
||||||
|
args = (sys.stderr,)
|
||||||
|
level = NOTSET
|
||||||
|
formatter = generic
|
||||||
|
|
||||||
|
[formatter_generic]
|
||||||
|
format = %(levelname)-5.5s [%(name)s] %(message)s
|
||||||
|
datefmt = %H:%M:%S
|
1
alembic/README
Normal file
1
alembic/README
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Generic single-database configuration.
|
79
alembic/env.py
Normal file
79
alembic/env.py
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
from logging.config import fileConfig
|
||||||
|
|
||||||
|
from sqlalchemy import engine_from_config
|
||||||
|
from sqlalchemy import pool
|
||||||
|
|
||||||
|
from alembic import context
|
||||||
|
|
||||||
|
# this is the Alembic Config object, which provides
|
||||||
|
# access to the values within the .ini file in use.
|
||||||
|
config = context.config
|
||||||
|
|
||||||
|
# Interpret the config file for Python logging.
|
||||||
|
# This line sets up loggers basically.
|
||||||
|
fileConfig(config.config_file_name)
|
||||||
|
|
||||||
|
# add your model's MetaData object here
|
||||||
|
# for 'autogenerate' support
|
||||||
|
# from myapp import mymodel
|
||||||
|
# target_metadata = mymodel.Base.metadata
|
||||||
|
from mealie.db.models.model_base import SqlAlchemyBase as Base
|
||||||
|
import mealie.db.models._all_models
|
||||||
|
target_metadata = Base.metadata
|
||||||
|
|
||||||
|
# other values from the config, defined by the needs of env.py,
|
||||||
|
# can be acquired:
|
||||||
|
# my_important_option = config.get_main_option("my_important_option")
|
||||||
|
# ... etc.
|
||||||
|
|
||||||
|
|
||||||
|
def run_migrations_offline():
|
||||||
|
"""Run migrations in 'offline' mode.
|
||||||
|
|
||||||
|
This configures the context with just a URL
|
||||||
|
and not an Engine, though an Engine is acceptable
|
||||||
|
here as well. By skipping the Engine creation
|
||||||
|
we don't even need a DBAPI to be available.
|
||||||
|
|
||||||
|
Calls to context.execute() here emit the given string to the
|
||||||
|
script output.
|
||||||
|
|
||||||
|
"""
|
||||||
|
url = config.get_main_option("sqlalchemy.url")
|
||||||
|
context.configure(
|
||||||
|
url=url,
|
||||||
|
target_metadata=target_metadata,
|
||||||
|
literal_binds=True,
|
||||||
|
dialect_opts={"paramstyle": "named"},
|
||||||
|
)
|
||||||
|
|
||||||
|
with context.begin_transaction():
|
||||||
|
context.run_migrations()
|
||||||
|
|
||||||
|
|
||||||
|
def run_migrations_online():
|
||||||
|
"""Run migrations in 'online' mode.
|
||||||
|
|
||||||
|
In this scenario we need to create an Engine
|
||||||
|
and associate a connection with the context.
|
||||||
|
|
||||||
|
"""
|
||||||
|
connectable = engine_from_config(
|
||||||
|
config.get_section(config.config_ini_section),
|
||||||
|
prefix="sqlalchemy.",
|
||||||
|
poolclass=pool.NullPool,
|
||||||
|
)
|
||||||
|
|
||||||
|
with connectable.connect() as connection:
|
||||||
|
context.configure(
|
||||||
|
connection=connection, target_metadata=target_metadata
|
||||||
|
)
|
||||||
|
|
||||||
|
with context.begin_transaction():
|
||||||
|
context.run_migrations()
|
||||||
|
|
||||||
|
|
||||||
|
if context.is_offline_mode():
|
||||||
|
run_migrations_offline()
|
||||||
|
else:
|
||||||
|
run_migrations_online()
|
24
alembic/script.py.mako
Normal file
24
alembic/script.py.mako
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
"""${message}
|
||||||
|
|
||||||
|
Revision ID: ${up_revision}
|
||||||
|
Revises: ${down_revision | comma,n}
|
||||||
|
Create Date: ${create_date}
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
${imports if imports else ""}
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = ${repr(up_revision)}
|
||||||
|
down_revision = ${repr(down_revision)}
|
||||||
|
branch_labels = ${repr(branch_labels)}
|
||||||
|
depends_on = ${repr(depends_on)}
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
${upgrades if upgrades else "pass"}
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
${downgrades if downgrades else "pass"}
|
318
alembic/versions/89e8733c36f2_initial_revision.py
Normal file
318
alembic/versions/89e8733c36f2_initial_revision.py
Normal file
|
@ -0,0 +1,318 @@
|
||||||
|
"""Initial revision
|
||||||
|
|
||||||
|
Revision ID: 89e8733c36f2
|
||||||
|
Revises:
|
||||||
|
Create Date: 2021-04-27 23:37:22.500465
|
||||||
|
|
||||||
|
"""
|
||||||
|
from mealie.core.config import settings
|
||||||
|
from mealie.core.security import get_password_hash
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '89e8733c36f2'
|
||||||
|
down_revision = None
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
categories_table = op.create_table('categories',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('name', sa.String(), nullable=False),
|
||||||
|
sa.Column('slug', sa.String(), nullable=False),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
op.create_index(op.f('ix_categories_name'), 'categories', ['name'], unique=False)
|
||||||
|
op.create_index(op.f('ix_categories_slug'), 'categories', ['slug'], unique=True)
|
||||||
|
custom_pages_table = op.create_table('custom_pages',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('position', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('name', sa.String(), nullable=False),
|
||||||
|
sa.Column('slug', sa.String(), nullable=False),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
groups_table = op.create_table('groups',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('name', sa.String(), nullable=False),
|
||||||
|
sa.Column('webhook_enable', sa.Boolean(), nullable=True),
|
||||||
|
sa.Column('webhook_time', sa.String(), nullable=True),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
op.create_index(op.f('ix_groups_name'), 'groups', ['name'], unique=True)
|
||||||
|
recipes_table = op.create_table('recipes',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('name', sa.String(), nullable=False),
|
||||||
|
sa.Column('description', sa.String(), nullable=True),
|
||||||
|
sa.Column('image', sa.String(), nullable=True),
|
||||||
|
sa.Column('totalTime', sa.String(), nullable=True),
|
||||||
|
sa.Column('prepTime', sa.String(), nullable=True),
|
||||||
|
sa.Column('performTime', sa.String(), nullable=True),
|
||||||
|
sa.Column('cookTime', sa.String(), nullable=True),
|
||||||
|
sa.Column('recipeYield', sa.String(), nullable=True),
|
||||||
|
sa.Column('recipeCuisine', sa.String(), nullable=True),
|
||||||
|
sa.Column('slug', sa.String(), nullable=True),
|
||||||
|
sa.Column('dateAdded', sa.Date(), nullable=True),
|
||||||
|
sa.Column('rating', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('orgURL', sa.String(), nullable=True),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
op.create_index(op.f('ix_recipes_slug'), 'recipes', ['slug'], unique=True)
|
||||||
|
sign_ups_table = op.create_table('sign_ups',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('token', sa.String(), nullable=False),
|
||||||
|
sa.Column('name', sa.String(), nullable=True),
|
||||||
|
sa.Column('admin', sa.Boolean(), nullable=True),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
op.create_index(op.f('ix_sign_ups_name'), 'sign_ups', ['name'], unique=False)
|
||||||
|
op.create_index(op.f('ix_sign_ups_token'), 'sign_ups', ['token'], unique=False)
|
||||||
|
site_settings_table = op.create_table('site_settings',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('language', sa.String(), nullable=True),
|
||||||
|
sa.Column('show_recent', sa.Boolean(), nullable=True),
|
||||||
|
sa.Column('cards_per_section', sa.Integer(), nullable=True),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
site_theme_table = op.create_table('site_theme',
|
||||||
|
sa.Column('name', sa.String(), nullable=False),
|
||||||
|
sa.PrimaryKeyConstraint('name')
|
||||||
|
)
|
||||||
|
tags_table = op.create_table('tags',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('name', sa.String(), nullable=False),
|
||||||
|
sa.Column('slug', sa.String(), nullable=False),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
op.create_index(op.f('ix_tags_name'), 'tags', ['name'], unique=False)
|
||||||
|
op.create_index(op.f('ix_tags_slug'), 'tags', ['slug'], unique=True)
|
||||||
|
api_extras_table = op.create_table('api_extras',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('parent_id', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('key_name', sa.String(), nullable=True),
|
||||||
|
sa.Column('value', sa.String(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['parent_id'], ['recipes.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
sa.UniqueConstraint('key_name')
|
||||||
|
)
|
||||||
|
custom_pages2categories_table = op.create_table('custom_pages2categories',
|
||||||
|
sa.Column('custom_page_id', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('category_slug', sa.String(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['category_slug'], ['categories.slug'], ),
|
||||||
|
sa.ForeignKeyConstraint(['custom_page_id'], ['custom_pages.id'], )
|
||||||
|
)
|
||||||
|
group2categories_table = op.create_table('group2categories',
|
||||||
|
sa.Column('group_id', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('category_slug', sa.String(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['category_slug'], ['categories.slug'], ),
|
||||||
|
sa.ForeignKeyConstraint(['group_id'], ['groups.id'], )
|
||||||
|
)
|
||||||
|
mealplan_table = op.create_table('mealplan',
|
||||||
|
sa.Column('uid', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('startDate', sa.Date(), nullable=True),
|
||||||
|
sa.Column('endDate', sa.Date(), nullable=True),
|
||||||
|
sa.Column('group_id', sa.Integer(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['group_id'], ['groups.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('uid'),
|
||||||
|
sa.UniqueConstraint('uid')
|
||||||
|
)
|
||||||
|
notes_table = op.create_table('notes',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('parent_id', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('title', sa.String(), nullable=True),
|
||||||
|
sa.Column('text', sa.String(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['parent_id'], ['recipes.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
recipe_instructions_table = op.create_table('recipe_instructions',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('parent_id', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('position', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('type', sa.String(), nullable=True),
|
||||||
|
sa.Column('text', sa.String(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['parent_id'], ['recipes.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
recipe_nutrition_table = op.create_table('recipe_nutrition',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('parent_id', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('calories', sa.String(), nullable=True),
|
||||||
|
sa.Column('fatContent', sa.String(), nullable=True),
|
||||||
|
sa.Column('fiberContent', sa.String(), nullable=True),
|
||||||
|
sa.Column('proteinContent', sa.String(), nullable=True),
|
||||||
|
sa.Column('sodiumContent', sa.String(), nullable=True),
|
||||||
|
sa.Column('sugarContent', sa.String(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['parent_id'], ['recipes.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
recipes2categories_table = op.create_table('recipes2categories',
|
||||||
|
sa.Column('recipe_id', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('category_slug', sa.String(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['category_slug'], ['categories.slug'], ),
|
||||||
|
sa.ForeignKeyConstraint(['recipe_id'], ['recipes.id'], )
|
||||||
|
)
|
||||||
|
recipes2tags_table = op.create_table('recipes2tags',
|
||||||
|
sa.Column('recipe_id', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('tag_slug', sa.String(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['recipe_id'], ['recipes.id'], ),
|
||||||
|
sa.ForeignKeyConstraint(['tag_slug'], ['tags.slug'], )
|
||||||
|
)
|
||||||
|
recipes_ingredients_table = op.create_table('recipes_ingredients',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('position', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('parent_id', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('ingredient', sa.String(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['parent_id'], ['recipes.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
site_settings2categories_table = op.create_table('site_settings2categories_table',
|
||||||
|
sa.Column('sidebar_id', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('category_slug', sa.String(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['category_slug'], ['categories.slug'], ),
|
||||||
|
sa.ForeignKeyConstraint(['sidebar_id'], ['site_settings.id'], )
|
||||||
|
)
|
||||||
|
theme_colors_table = op.create_table('theme_colors',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('parent_id', sa.String(), nullable=True),
|
||||||
|
sa.Column('primary', sa.String(), nullable=True),
|
||||||
|
sa.Column('accent', sa.String(), nullable=True),
|
||||||
|
sa.Column('secondary', sa.String(), nullable=True),
|
||||||
|
sa.Column('success', sa.String(), nullable=True),
|
||||||
|
sa.Column('info', sa.String(), nullable=True),
|
||||||
|
sa.Column('warning', sa.String(), nullable=True),
|
||||||
|
sa.Column('error', sa.String(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['parent_id'], ['site_theme.name'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
tools_table = op.create_table('tools',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('parent_id', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('tool', sa.String(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['parent_id'], ['recipes.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
users_table = op.create_table('users',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('full_name', sa.String(), nullable=True),
|
||||||
|
sa.Column('email', sa.String(), nullable=True),
|
||||||
|
sa.Column('password', sa.String(), nullable=True),
|
||||||
|
sa.Column('group_id', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('admin', sa.Boolean(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['group_id'], ['groups.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
op.create_index(op.f('ix_users_email'), 'users', ['email'], unique=True)
|
||||||
|
op.create_index(op.f('ix_users_full_name'), 'users', ['full_name'], unique=False)
|
||||||
|
webhook_urls_table = op.create_table('webhook_urls',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('url', sa.String(), nullable=True),
|
||||||
|
sa.Column('parent_id', sa.Integer(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['parent_id'], ['groups.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
meal_table = op.create_table('meal',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('parent_id', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('slug', sa.String(), nullable=True),
|
||||||
|
sa.Column('name', sa.String(), nullable=True),
|
||||||
|
sa.Column('date', sa.Date(), nullable=True),
|
||||||
|
sa.Column('image', sa.String(), nullable=True),
|
||||||
|
sa.Column('description', sa.String(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['parent_id'], ['mealplan.uid'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
# seed data
|
||||||
|
op.bulk_insert(site_settings_table, [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"language": "en",
|
||||||
|
"firstDayOfWeek": 0,
|
||||||
|
"showRecent": True,
|
||||||
|
}
|
||||||
|
])
|
||||||
|
op.bulk_insert(categories_table, [
|
||||||
|
{"id": 1, "name": "thanksgiving", "slug": "thanksgiving"},
|
||||||
|
{"id": 2, "name": "homechef", "slug": "homechef"},
|
||||||
|
{"id": 3, "name": "potatoes", "slug": "potatoes"},
|
||||||
|
])
|
||||||
|
op.bulk_insert(site_settings2categories_table, [
|
||||||
|
{
|
||||||
|
"sidebar_id": 1,
|
||||||
|
"category_slug", "thanksgiving",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sidebar_id": 1,
|
||||||
|
"category_slug", "homechef",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sidebar_id": 1,
|
||||||
|
"category_slug", "potatoes",
|
||||||
|
},
|
||||||
|
])
|
||||||
|
op.bulk_insert(site_theme_table, [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"colors": {
|
||||||
|
"primary": "#E58325",
|
||||||
|
"accent": "#00457A",
|
||||||
|
"secondary": "#973542",
|
||||||
|
"success": "#5AB1BB",
|
||||||
|
"info": "#4990BA",
|
||||||
|
"warning": "#FF4081",
|
||||||
|
"error": "#EF5350",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
op.bulk_insert(groups_table, [
|
||||||
|
{
|
||||||
|
"name": settings.DEFAULT_GROUP,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
op.bulk_insert(users_table, [
|
||||||
|
{
|
||||||
|
"full_name": "Change Me",
|
||||||
|
"email": settings.DEFAULT_EMAIL,
|
||||||
|
"password": get_password_hash(settings.DEFAULT_PASSWORD),
|
||||||
|
"group": settings.DEFAULT_GROUP,
|
||||||
|
"admin": True,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
op.drop_table('meal')
|
||||||
|
op.drop_table('webhook_urls')
|
||||||
|
op.drop_index(op.f('ix_users_full_name'), table_name='users')
|
||||||
|
op.drop_index(op.f('ix_users_email'), table_name='users')
|
||||||
|
op.drop_table('users')
|
||||||
|
op.drop_table('tools')
|
||||||
|
op.drop_table('theme_colors')
|
||||||
|
op.drop_table('site_settings2categories')
|
||||||
|
op.drop_table('recipes_ingredients')
|
||||||
|
op.drop_table('recipes2tags')
|
||||||
|
op.drop_table('recipes2categories')
|
||||||
|
op.drop_table('recipe_nutrition')
|
||||||
|
op.drop_table('recipe_instructions')
|
||||||
|
op.drop_table('notes')
|
||||||
|
op.drop_table('mealplan')
|
||||||
|
op.drop_table('group2categories')
|
||||||
|
op.drop_table('custom_pages2categories')
|
||||||
|
op.drop_table('api_extras')
|
||||||
|
op.drop_index(op.f('ix_tags_slug'), table_name='tags')
|
||||||
|
op.drop_index(op.f('ix_tags_name'), table_name='tags')
|
||||||
|
op.drop_table('tags')
|
||||||
|
op.drop_table('site_theme')
|
||||||
|
op.drop_table('site_settings')
|
||||||
|
op.drop_index(op.f('ix_sign_ups_token'), table_name='sign_ups')
|
||||||
|
op.drop_index(op.f('ix_sign_ups_name'), table_name='sign_ups')
|
||||||
|
op.drop_table('sign_ups')
|
||||||
|
op.drop_index(op.f('ix_recipes_slug'), table_name='recipes')
|
||||||
|
op.drop_table('recipes')
|
||||||
|
op.drop_index(op.f('ix_groups_name'), table_name='groups')
|
||||||
|
op.drop_table('groups')
|
||||||
|
op.drop_table('custom_pages')
|
||||||
|
op.drop_index(op.f('ix_categories_slug'), table_name='categories')
|
||||||
|
op.drop_index(op.f('ix_categories_name'), table_name='categories')
|
||||||
|
op.drop_table('categories')
|
|
@ -123,7 +123,7 @@ The frontend static files are generated with `npm run build`. This is done durin
|
||||||
### Backend API
|
### Backend API
|
||||||
The backend API is build with Python, FastAPI, and SQLite and requires Python 3.9, and Poetry. Once the requirements are installed, in the project directory you can run the command `poetry install` to create a python virtual environment and install the python dependencies.
|
The backend API is build with Python, FastAPI, and SQLite and requires Python 3.9, and Poetry. Once the requirements are installed, in the project directory you can run the command `poetry install` to create a python virtual environment and install the python dependencies.
|
||||||
|
|
||||||
Once the dependencies are installed you should be ready to run the server. To initialize that database you need to first run `python mealie/db/init_db.py`. Then to start The web server, you run the command `uvicorn mealie.app:app --host 0.0.0.0 --port 9000`
|
Once the dependencies are installed you should be ready to run the server. To initialize that database you need to first run `alembic upgrade head`. Then to start The web server, you run the command `uvicorn mealie.app:app --host 0.0.0.0 --port 9000`
|
||||||
|
|
||||||
|
|
||||||
### Proxy Server
|
### Proxy Server
|
||||||
|
|
2
makefile
2
makefile
|
@ -53,7 +53,7 @@ setup: ## Setup Development Instance
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
backend: ## Start Mealie Backend Development Server
|
backend: ## Start Mealie Backend Development Server
|
||||||
poetry run python mealie/db/init_db.py && \
|
poetry run alembic upgrade head && \
|
||||||
poetry run python mealie/services/image/minify.py && \
|
poetry run python mealie/services/image/minify.py && \
|
||||||
poetry run python mealie/app.py
|
poetry run python mealie/app.py
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,6 @@ from sqlalchemy.orm.session import Session
|
||||||
|
|
||||||
from mealie.db.models.db_session import sql_global_init
|
from mealie.db.models.db_session import sql_global_init
|
||||||
|
|
||||||
sql_exists = True
|
|
||||||
|
|
||||||
SessionLocal = sql_global_init(settings.DB_URL)
|
SessionLocal = sql_global_init(settings.DB_URL)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
from mealie.core import root_logger
|
|
||||||
from mealie.core.config import settings
|
|
||||||
from mealie.core.security import get_password_hash
|
|
||||||
from mealie.db.database import db
|
|
||||||
from mealie.db.db_setup import create_session, sql_exists
|
|
||||||
from mealie.schema.settings import SiteSettings
|
|
||||||
from mealie.schema.theme import SiteTheme
|
|
||||||
from sqlalchemy.orm import Session
|
|
||||||
|
|
||||||
logger = root_logger.get_logger("init_db")
|
|
||||||
|
|
||||||
|
|
||||||
def init_db(db: Session = None) -> None:
|
|
||||||
if not db:
|
|
||||||
db = create_session()
|
|
||||||
|
|
||||||
default_group_init(db)
|
|
||||||
default_settings_init(db)
|
|
||||||
default_theme_init(db)
|
|
||||||
default_user_init(db)
|
|
||||||
|
|
||||||
db.close()
|
|
||||||
|
|
||||||
|
|
||||||
def default_theme_init(session: Session):
|
|
||||||
db.themes.create(session, SiteTheme().dict())
|
|
||||||
|
|
||||||
|
|
||||||
def default_settings_init(session: Session):
|
|
||||||
document = db.settings.create(session, SiteSettings().dict())
|
|
||||||
logger.info(f"Created Site Settings: \n {document}")
|
|
||||||
|
|
||||||
|
|
||||||
def default_group_init(session: Session):
|
|
||||||
default_group = {"name": settings.DEFAULT_GROUP}
|
|
||||||
logger.info("Generating Default Group")
|
|
||||||
db.groups.create(session, default_group)
|
|
||||||
|
|
||||||
|
|
||||||
def default_user_init(session: Session):
|
|
||||||
default_user = {
|
|
||||||
"full_name": "Change Me",
|
|
||||||
"email": settings.DEFAULT_EMAIL,
|
|
||||||
"password": get_password_hash(settings.DEFAULT_PASSWORD),
|
|
||||||
"group": settings.DEFAULT_GROUP,
|
|
||||||
"admin": True,
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info("Generating Default User")
|
|
||||||
db.users.create(session, default_user)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
if sql_exists:
|
|
||||||
print("Database Exists")
|
|
||||||
else:
|
|
||||||
print("Database Doesn't Exists, Initializing...")
|
|
||||||
init_db()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
|
@ -13,8 +13,4 @@ def sql_global_init(db_url: str):
|
||||||
|
|
||||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||||
|
|
||||||
import mealie.db.models._all_models # noqa: F401
|
|
||||||
|
|
||||||
SqlAlchemyBase.metadata.create_all(engine)
|
|
||||||
|
|
||||||
return SessionLocal
|
return SessionLocal
|
||||||
|
|
|
@ -8,7 +8,7 @@ from sqlalchemy.orm import validates
|
||||||
logger = root_logger.get_logger()
|
logger = root_logger.get_logger()
|
||||||
|
|
||||||
site_settings2categories = sa.Table(
|
site_settings2categories = sa.Table(
|
||||||
"site_settings2categoories",
|
"site_settings2categories",
|
||||||
SqlAlchemyBase.metadata,
|
SqlAlchemyBase.metadata,
|
||||||
sa.Column("sidebar_id", sa.Integer, sa.ForeignKey("site_settings.id")),
|
sa.Column("sidebar_id", sa.Integer, sa.ForeignKey("site_settings.id")),
|
||||||
sa.Column("category_id", sa.String, sa.ForeignKey("categories.id")),
|
sa.Column("category_id", sa.String, sa.ForeignKey("categories.id")),
|
||||||
|
|
|
@ -11,11 +11,7 @@ recipes2tags = sa.Table(
|
||||||
"recipes2tags",
|
"recipes2tags",
|
||||||
SqlAlchemyBase.metadata,
|
SqlAlchemyBase.metadata,
|
||||||
sa.Column("recipe_id", sa.Integer, sa.ForeignKey("recipes.id")),
|
sa.Column("recipe_id", sa.Integer, sa.ForeignKey("recipes.id")),
|
||||||
<<<<<<< HEAD
|
|
||||||
sa.Column("tag_id", sa.Integer, sa.ForeignKey("tags.id")),
|
sa.Column("tag_id", sa.Integer, sa.ForeignKey("tags.id")),
|
||||||
=======
|
|
||||||
sa.Column("tag_slug", sa.String, sa.ForeignKey("tags.slug")),
|
|
||||||
>>>>>>> e2e2ad5 (feat: other databases support)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
mealie/mealie.db
Normal file
BIN
mealie/mealie.db
Normal file
Binary file not shown.
|
@ -7,7 +7,7 @@ ARG1=${1:-production}
|
||||||
# DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
# DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
|
|
||||||
# # Initialize Database Prerun
|
# # Initialize Database Prerun
|
||||||
poetry run python /app/mealie/db/init_db.py
|
poetry run alembic upgrade head
|
||||||
poetry run python /app/mealie/services/image/minify.py
|
poetry run python /app/mealie/services/image/minify.py
|
||||||
|
|
||||||
# Migrations
|
# Migrations
|
||||||
|
|
|
@ -16,6 +16,7 @@ class SiteSettings(CamelModel):
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
orm_mode = True
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
schema_extra = {
|
schema_extra = {
|
||||||
"example": {
|
"example": {
|
||||||
"language": "en",
|
"language": "en",
|
||||||
|
@ -29,6 +30,8 @@ class SiteSettings(CamelModel):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> 0afdaf6 (Add alembic)
|
||||||
|
|
||||||
class CustomPageBase(CamelModel):
|
class CustomPageBase(CamelModel):
|
||||||
name: str
|
name: str
|
||||||
|
|
|
@ -20,17 +20,3 @@ class SiteTheme(BaseModel):
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
orm_mode = True
|
||||||
schema_extra = {
|
|
||||||
"example": {
|
|
||||||
"name": "default",
|
|
||||||
"colors": {
|
|
||||||
"primary": "#E58325",
|
|
||||||
"accent": "#00457A",
|
|
||||||
"secondary": "#973542",
|
|
||||||
"success": "#5AB1BB",
|
|
||||||
"info": "#4990BA",
|
|
||||||
"warning": "#FF4081",
|
|
||||||
"error": "#EF5350",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
76
poetry.lock
generated
76
poetry.lock
generated
|
@ -6,6 +6,20 @@ category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "alembic"
|
||||||
|
version = "1.5.8"
|
||||||
|
description = "A database migration tool for SQLAlchemy."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
Mako = "*"
|
||||||
|
python-dateutil = "*"
|
||||||
|
python-editor = ">=0.3"
|
||||||
|
SQLAlchemy = ">=1.3.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aniso8601"
|
name = "aniso8601"
|
||||||
version = "7.0.0"
|
version = "7.0.0"
|
||||||
|
@ -460,6 +474,21 @@ html5 = ["html5lib"]
|
||||||
htmlsoup = ["beautifulsoup4"]
|
htmlsoup = ["beautifulsoup4"]
|
||||||
source = ["Cython (>=0.29.7)"]
|
source = ["Cython (>=0.29.7)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mako"
|
||||||
|
version = "1.1.4"
|
||||||
|
description = "A super-fast templating language that borrows the best ideas from the existing templating languages."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
MarkupSafe = ">=0.9.2"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
babel = ["babel"]
|
||||||
|
lingua = ["lingua"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "markdown"
|
name = "markdown"
|
||||||
version = "3.3.4"
|
version = "3.3.4"
|
||||||
|
@ -792,6 +821,17 @@ pytest = ">=4.6"
|
||||||
[package.extras]
|
[package.extras]
|
||||||
testing = ["fields", "hunter", "process-tests (==2.0.2)", "six", "pytest-xdist", "virtualenv"]
|
testing = ["fields", "hunter", "process-tests (==2.0.2)", "six", "pytest-xdist", "virtualenv"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "python-dateutil"
|
||||||
|
version = "2.8.1"
|
||||||
|
description = "Extensions to the standard Python datetime module"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
six = ">=1.5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "python-dotenv"
|
name = "python-dotenv"
|
||||||
version = "0.15.0"
|
version = "0.15.0"
|
||||||
|
@ -803,6 +843,14 @@ python-versions = "*"
|
||||||
[package.extras]
|
[package.extras]
|
||||||
cli = ["click (>=5.0)"]
|
cli = ["click (>=5.0)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "python-editor"
|
||||||
|
version = "1.0.4"
|
||||||
|
description = "Programmatically open an editor, capture the result."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "python-jose"
|
name = "python-jose"
|
||||||
version = "3.2.0"
|
version = "3.2.0"
|
||||||
|
@ -1175,13 +1223,17 @@ python-versions = "*"
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.9"
|
python-versions = "^3.9"
|
||||||
content-hash = "bfdb4d3d5d69e53f16b315f993b712a703058d3f59e24644681ccc9062cf5143"
|
content-hash = "2e18cdb78fe35d17c6018a71ed28cdb545f73fa60030a999a3c90bb9a9a1b245"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
aiofiles = [
|
aiofiles = [
|
||||||
{file = "aiofiles-0.5.0-py3-none-any.whl", hash = "sha256:377fdf7815cc611870c59cbd07b68b180841d2a2b79812d8c218be02448c2acb"},
|
{file = "aiofiles-0.5.0-py3-none-any.whl", hash = "sha256:377fdf7815cc611870c59cbd07b68b180841d2a2b79812d8c218be02448c2acb"},
|
||||||
{file = "aiofiles-0.5.0.tar.gz", hash = "sha256:98e6bcfd1b50f97db4980e182ddd509b7cc35909e903a8fe50d8849e02d815af"},
|
{file = "aiofiles-0.5.0.tar.gz", hash = "sha256:98e6bcfd1b50f97db4980e182ddd509b7cc35909e903a8fe50d8849e02d815af"},
|
||||||
]
|
]
|
||||||
|
alembic = [
|
||||||
|
{file = "alembic-1.5.8-py2.py3-none-any.whl", hash = "sha256:8a259f0a4c8b350b03579d77ce9e810b19c65bf0af05f84efb69af13ad50801e"},
|
||||||
|
{file = "alembic-1.5.8.tar.gz", hash = "sha256:e27fd67732c97a1c370c33169ef4578cf96436fa0e7dcfaeeef4a917d0737d56"},
|
||||||
|
]
|
||||||
aniso8601 = [
|
aniso8601 = [
|
||||||
{file = "aniso8601-7.0.0-py2.py3-none-any.whl", hash = "sha256:d10a4bf949f619f719b227ef5386e31f49a2b6d453004b21f02661ccc8670c7b"},
|
{file = "aniso8601-7.0.0-py2.py3-none-any.whl", hash = "sha256:d10a4bf949f619f719b227ef5386e31f49a2b6d453004b21f02661ccc8670c7b"},
|
||||||
{file = "aniso8601-7.0.0.tar.gz", hash = "sha256:513d2b6637b7853806ae79ffaca6f3e8754bdd547048f5ccc1420aec4b714f1e"},
|
{file = "aniso8601-7.0.0.tar.gz", hash = "sha256:513d2b6637b7853806ae79ffaca6f3e8754bdd547048f5ccc1420aec4b714f1e"},
|
||||||
|
@ -1526,6 +1578,9 @@ lxml = [
|
||||||
{file = "lxml-4.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:535332fe9d00c3cd455bd3dd7d4bacab86e2d564bdf7606079160fa6251caacf"},
|
{file = "lxml-4.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:535332fe9d00c3cd455bd3dd7d4bacab86e2d564bdf7606079160fa6251caacf"},
|
||||||
{file = "lxml-4.6.2.tar.gz", hash = "sha256:cd11c7e8d21af997ee8079037fff88f16fda188a9776eb4b81c7e4c9c0a7d7fc"},
|
{file = "lxml-4.6.2.tar.gz", hash = "sha256:cd11c7e8d21af997ee8079037fff88f16fda188a9776eb4b81c7e4c9c0a7d7fc"},
|
||||||
]
|
]
|
||||||
|
mako = [
|
||||||
|
{file = "Mako-1.1.4.tar.gz", hash = "sha256:17831f0b7087c313c0ffae2bcbbd3c1d5ba9eeac9c38f2eb7b50e8c99fe9d5ab"},
|
||||||
|
]
|
||||||
markdown = [
|
markdown = [
|
||||||
{file = "Markdown-3.3.4-py3-none-any.whl", hash = "sha256:96c3ba1261de2f7547b46a00ea8463832c921d3f9d6aba3f255a6f71386db20c"},
|
{file = "Markdown-3.3.4-py3-none-any.whl", hash = "sha256:96c3ba1261de2f7547b46a00ea8463832c921d3f9d6aba3f255a6f71386db20c"},
|
||||||
{file = "Markdown-3.3.4.tar.gz", hash = "sha256:31b5b491868dcc87d6c24b7e3d19a0d730d59d3e46f4eea6430a321bed387a49"},
|
{file = "Markdown-3.3.4.tar.gz", hash = "sha256:31b5b491868dcc87d6c24b7e3d19a0d730d59d3e46f4eea6430a321bed387a49"},
|
||||||
|
@ -1752,10 +1807,21 @@ pytest-cov = [
|
||||||
{file = "pytest-cov-2.11.1.tar.gz", hash = "sha256:359952d9d39b9f822d9d29324483e7ba04a3a17dd7d05aa6beb7ea01e359e5f7"},
|
{file = "pytest-cov-2.11.1.tar.gz", hash = "sha256:359952d9d39b9f822d9d29324483e7ba04a3a17dd7d05aa6beb7ea01e359e5f7"},
|
||||||
{file = "pytest_cov-2.11.1-py2.py3-none-any.whl", hash = "sha256:bdb9fdb0b85a7cc825269a4c56b48ccaa5c7e365054b6038772c32ddcdc969da"},
|
{file = "pytest_cov-2.11.1-py2.py3-none-any.whl", hash = "sha256:bdb9fdb0b85a7cc825269a4c56b48ccaa5c7e365054b6038772c32ddcdc969da"},
|
||||||
]
|
]
|
||||||
|
python-dateutil = [
|
||||||
|
{file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"},
|
||||||
|
{file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"},
|
||||||
|
]
|
||||||
python-dotenv = [
|
python-dotenv = [
|
||||||
{file = "python-dotenv-0.15.0.tar.gz", hash = "sha256:587825ed60b1711daea4832cf37524dfd404325b7db5e25ebe88c495c9f807a0"},
|
{file = "python-dotenv-0.15.0.tar.gz", hash = "sha256:587825ed60b1711daea4832cf37524dfd404325b7db5e25ebe88c495c9f807a0"},
|
||||||
{file = "python_dotenv-0.15.0-py2.py3-none-any.whl", hash = "sha256:0c8d1b80d1a1e91717ea7d526178e3882732420b03f08afea0406db6402e220e"},
|
{file = "python_dotenv-0.15.0-py2.py3-none-any.whl", hash = "sha256:0c8d1b80d1a1e91717ea7d526178e3882732420b03f08afea0406db6402e220e"},
|
||||||
]
|
]
|
||||||
|
python-editor = [
|
||||||
|
{file = "python-editor-1.0.4.tar.gz", hash = "sha256:51fda6bcc5ddbbb7063b2af7509e43bd84bfc32a4ff71349ec7847713882327b"},
|
||||||
|
{file = "python_editor-1.0.4-py2-none-any.whl", hash = "sha256:5f98b069316ea1c2ed3f67e7f5df6c0d8f10b689964a4a811ff64f0106819ec8"},
|
||||||
|
{file = "python_editor-1.0.4-py2.7.egg", hash = "sha256:ea87e17f6ec459e780e4221f295411462e0d0810858e055fc514684350a2f522"},
|
||||||
|
{file = "python_editor-1.0.4-py3-none-any.whl", hash = "sha256:1bf6e860a8ad52a14c3ee1252d5dc25b2030618ed80c022598f00176adc8367d"},
|
||||||
|
{file = "python_editor-1.0.4-py3.5.egg", hash = "sha256:c3da2053dbab6b29c94e43c486ff67206eafbe7eb52dbec7390b5e2fb05aac77"},
|
||||||
|
]
|
||||||
python-jose = [
|
python-jose = [
|
||||||
{file = "python-jose-3.2.0.tar.gz", hash = "sha256:4e4192402e100b5fb09de5a8ea6bcc39c36ad4526341c123d401e2561720335b"},
|
{file = "python-jose-3.2.0.tar.gz", hash = "sha256:4e4192402e100b5fb09de5a8ea6bcc39c36ad4526341c123d401e2561720335b"},
|
||||||
{file = "python_jose-3.2.0-py2.py3-none-any.whl", hash = "sha256:67d7dfff599df676b04a996520d9be90d6cdb7e6dd10b4c7cacc0c3e2e92f2be"},
|
{file = "python_jose-3.2.0-py2.py3-none-any.whl", hash = "sha256:67d7dfff599df676b04a996520d9be90d6cdb7e6dd10b4c7cacc0c3e2e92f2be"},
|
||||||
|
@ -1777,26 +1843,18 @@ pyyaml = [
|
||||||
{file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"},
|
{file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"},
|
||||||
{file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"},
|
{file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"},
|
||||||
{file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"},
|
{file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"},
|
||||||
{file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"},
|
|
||||||
{file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"},
|
|
||||||
{file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"},
|
{file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"},
|
||||||
{file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"},
|
{file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"},
|
||||||
{file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"},
|
{file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"},
|
||||||
{file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"},
|
{file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"},
|
||||||
{file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"},
|
|
||||||
{file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"},
|
|
||||||
{file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"},
|
{file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"},
|
||||||
{file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"},
|
{file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"},
|
||||||
{file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"},
|
{file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"},
|
||||||
{file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"},
|
{file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"},
|
||||||
{file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"},
|
|
||||||
{file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"},
|
|
||||||
{file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"},
|
{file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"},
|
||||||
{file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"},
|
{file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"},
|
||||||
{file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"},
|
{file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"},
|
||||||
{file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"},
|
{file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"},
|
||||||
{file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"},
|
|
||||||
{file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"},
|
|
||||||
{file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"},
|
{file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"},
|
||||||
{file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"},
|
{file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"},
|
||||||
{file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"},
|
{file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"},
|
||||||
|
|
|
@ -32,6 +32,7 @@ passlib = "^1.7.4"
|
||||||
lxml = "4.6.2"
|
lxml = "4.6.2"
|
||||||
Pillow = "^8.2.0"
|
Pillow = "^8.2.0"
|
||||||
pathvalidate = "^2.4.1"
|
pathvalidate = "^2.4.1"
|
||||||
|
alembic = "^1.5.8"
|
||||||
|
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
|
|
|
@ -5,7 +5,6 @@ from fastapi.testclient import TestClient
|
||||||
from mealie.app import app
|
from mealie.app import app
|
||||||
from mealie.core.config import app_dirs, settings
|
from mealie.core.config import app_dirs, settings
|
||||||
from mealie.db.db_setup import generate_session, sql_global_init
|
from mealie.db.db_setup import generate_session, sql_global_init
|
||||||
from mealie.db.init_db import init_db
|
|
||||||
from pytest import fixture
|
from pytest import fixture
|
||||||
|
|
||||||
from tests.app_routes import AppRoutes
|
from tests.app_routes import AppRoutes
|
||||||
|
@ -17,7 +16,6 @@ SQLITE_FILE.unlink(missing_ok=True)
|
||||||
|
|
||||||
|
|
||||||
TestSessionLocal = sql_global_init(SQLITE_FILE)
|
TestSessionLocal = sql_global_init(SQLITE_FILE)
|
||||||
init_db(TestSessionLocal())
|
|
||||||
|
|
||||||
|
|
||||||
def override_get_db():
|
def override_get_db():
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue