![google-labs-jules[bot]](/assets/img/avatar_default.png)
This commit addresses issues with backend models, schemas, and migrations. Key changes: - Consolidated all SQLAlchemy model definitions into `be/app/models.py`. - Emptied `be/app/models/expense.py` as its contents were duplicates. - Verified and standardized Base class usage and SQLAlchemy imports in models. - Confirmed the correctness of self-referential relationships in the `Expense` model. - Added a clarifying comment to `SplitTypeEnum` regarding future extensibility. - Corrected a typo in `Settlement.created_by_user_id`. Migration Cleanup: - Deleted all existing Alembic migration files from `be/alembic/versions/`. - Created a new, single initial migration script (`0001_initial_schema.py`) that defines the entire database schema based on the current state of the SQLAlchemy models. This provides a clean slate for future migrations. This reset was performed because the previous migration history was complex and contained a revision that was incompatible with the current model definitions. Starting fresh ensures consistency between the models and the database schema from the initial point.
108 lines
3.6 KiB
Python
108 lines
3.6 KiB
Python
from logging.config import fileConfig
|
|
import os
|
|
import sys
|
|
import asyncio # Add this import
|
|
|
|
from sqlalchemy import engine_from_config
|
|
from sqlalchemy import pool
|
|
from sqlalchemy.ext.asyncio import create_async_engine # Add this specific import
|
|
|
|
from alembic import context
|
|
|
|
|
|
# Ensure the 'app' directory is in the Python path
|
|
# Adjust the path if your project structure is different
|
|
sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), '..')))
|
|
|
|
# Import your app's Base and settings
|
|
import app.models # Ensure all models are loaded and registered to app.database.Base
|
|
from app.database import Base as DatabaseBase # Explicitly get Base from database.py
|
|
from app.config import settings # Import settings to get DATABASE_URL
|
|
|
|
# this is the Alembic Config object, which provides
|
|
# access to the values within the .ini file in use.
|
|
config = context.config
|
|
|
|
# Set the sqlalchemy.url from your application settings
|
|
# Ensure DATABASE_URL is available and use it directly
|
|
if not settings.DATABASE_URL:
|
|
raise ValueError("DATABASE_URL not found in settings for Alembic.")
|
|
config.set_main_option('sqlalchemy.url', settings.DATABASE_URL)
|
|
|
|
|
|
# Interpret the config file for Python logging.
|
|
# This line sets up loggers basically.
|
|
if config.config_file_name is not None:
|
|
fileConfig(config.config_file_name)
|
|
|
|
# add your model's MetaData object here
|
|
# for 'autogenerate' support
|
|
# from myapp import mymodel
|
|
# target_metadata = mymodel.Base.metadata
|
|
target_metadata = DatabaseBase.metadata # Use metadata from app.database.Base
|
|
|
|
# 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() -> None:
|
|
"""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()
|
|
|
|
|
|
async def run_migrations_online_async() -> None: # Renamed and make async
|
|
"""Run migrations in 'online' mode.
|
|
|
|
In this scenario we need to create an Engine
|
|
and associate a connection with the context.
|
|
|
|
"""
|
|
# connectable here will be an AsyncEngine if the URL is asyncpg
|
|
db_url = config.get_main_option("sqlalchemy.url") # Get the async URL
|
|
if not db_url:
|
|
raise ValueError("Database URL is not configured in Alembic.")
|
|
|
|
connectable = create_async_engine(db_url, poolclass=pool.NullPool)
|
|
|
|
async with connectable.connect() as connection: # Use async with
|
|
# Pass target_metadata to the run_sync callback
|
|
await connection.run_sync(do_run_migrations, target_metadata)
|
|
|
|
await connectable.dispose() # Dispose of the async engine
|
|
|
|
def do_run_migrations(connection, metadata):
|
|
"""Helper function to configure and run migrations within a sync callback."""
|
|
context.configure(
|
|
connection=connection,
|
|
target_metadata=metadata
|
|
# Include other options like compare_type=True, compare_server_default=True if needed
|
|
)
|
|
with context.begin_transaction():
|
|
context.run_migrations()
|
|
|
|
if context.is_offline_mode():
|
|
run_migrations_offline()
|
|
else:
|
|
asyncio.run(run_migrations_online_async()) # Call the new async function
|