Add .env.example with configuration for database, Redis, security, SMTP, workers, and plugins. Add .gitignore for Python, Node.js, Next.js, Docker volumes, and IDE files. Add MIT License. Update README.md with feature overview, quick start guide, architecture description, plugin system documentation, security details, backup/restore instructions, and developer setup. Add Alembic configuration files and placeholder directories for API, web, worker, and plugin components
87 lines
1.9 KiB
Python
87 lines
1.9 KiB
Python
import asyncio
|
|
from logging.config import fileConfig
|
|
|
|
from alembic import context
|
|
from sqlalchemy import pool
|
|
from sqlalchemy.engine import Connection
|
|
from sqlalchemy.ext.asyncio import async_engine_from_config
|
|
|
|
from apps.api.src.config import settings
|
|
from apps.api.src.models.base import Base
|
|
|
|
# Import all models so Alembic can detect them
|
|
from apps.api.src.models import ( # noqa: F401
|
|
audit_log,
|
|
background_job,
|
|
dashboard,
|
|
notification,
|
|
plugin,
|
|
plugin_instance,
|
|
plugin_log,
|
|
plugin_version,
|
|
role,
|
|
secret,
|
|
service_connection,
|
|
session,
|
|
system_setting,
|
|
user,
|
|
widget,
|
|
api_token,
|
|
)
|
|
|
|
config = context.config
|
|
if config.config_file_name is not None:
|
|
fileConfig(config.config_file_name)
|
|
|
|
target_metadata = Base.metadata
|
|
|
|
|
|
def get_url() -> str:
|
|
return settings.DATABASE_URL
|
|
|
|
|
|
def run_migrations_offline() -> None:
|
|
url = get_url()
|
|
context.configure(
|
|
url=url,
|
|
target_metadata=target_metadata,
|
|
literal_binds=True,
|
|
dialect_opts={"paramstyle": "named"},
|
|
)
|
|
|
|
with context.begin_transaction():
|
|
context.run_migrations()
|
|
|
|
|
|
def do_run_migrations(connection: Connection) -> None:
|
|
context.configure(connection=connection, target_metadata=target_metadata)
|
|
|
|
with context.begin_transaction():
|
|
context.run_migrations()
|
|
|
|
|
|
async def run_async_migrations() -> None:
|
|
configuration = config.get_section(config.config_ini_section, {})
|
|
configuration["sqlalchemy.url"] = get_url()
|
|
|
|
connectable = async_engine_from_config(
|
|
configuration,
|
|
prefix="sqlalchemy.",
|
|
poolclass=pool.NullPool,
|
|
)
|
|
|
|
async with connectable.connect() as connection:
|
|
await connection.run_sync(do_run_migrations)
|
|
|
|
await connectable.dispose()
|
|
|
|
|
|
def run_migrations_online() -> None:
|
|
asyncio.run(run_async_migrations())
|
|
|
|
|
|
if context.is_offline_mode():
|
|
run_migrations_offline()
|
|
else:
|
|
run_migrations_online()
|