From cc39e79cd7bd68f22157c0505d0c501b473fac35 Mon Sep 17 00:00:00 2001 From: patrick Date: Mon, 10 Aug 2026 23:58:09 -0400 Subject: [PATCH] chore: regenerate initial migrations --- ...4_add_postgres_extensions_65aa95e8f8cf.py} | 24 +++-- ...-14_create_initial_tables_6d72d1bbc0ee.py} | 94 +++++++++++++++++-- backend/src/chitai/database/config.py | 7 +- 3 files changed, 106 insertions(+), 19 deletions(-) rename backend/migrations/versions/{2025-10-31_add_pg_trgm_extension_26022ec86f32.py => 2026-03-14_add_postgres_extensions_65aa95e8f8cf.py} (64%) rename backend/migrations/versions/{2026-03-08_create_initial_tables_43bdf42a4f6c.py => 2026-03-14_create_initial_tables_6d72d1bbc0ee.py} (72%) diff --git a/backend/migrations/versions/2025-10-31_add_pg_trgm_extension_26022ec86f32.py b/backend/migrations/versions/2026-03-14_add_postgres_extensions_65aa95e8f8cf.py similarity index 64% rename from backend/migrations/versions/2025-10-31_add_pg_trgm_extension_26022ec86f32.py rename to backend/migrations/versions/2026-03-14_add_postgres_extensions_65aa95e8f8cf.py index c0c39a6..642c42b 100644 --- a/backend/migrations/versions/2025-10-31_add_pg_trgm_extension_26022ec86f32.py +++ b/backend/migrations/versions/2026-03-14_add_postgres_extensions_65aa95e8f8cf.py @@ -1,8 +1,8 @@ -"""Add pg_trgm extension +"""add postgres extensions -Revision ID: 26022ec86f32 +Revision ID: 65aa95e8f8cf Revises: -Create Date: 2025-10-31 18:45:55.027462 +Create Date: 2026-03-14 11:59:55.364307 """ @@ -11,7 +11,12 @@ from typing import TYPE_CHECKING import sqlalchemy as sa from alembic import op -from advanced_alchemy.types import EncryptedString, EncryptedText, GUID, ORA_JSONB, DateTimeUTC, StoredObject, PasswordHash +from advanced_alchemy.types import EncryptedString, EncryptedText, GUID, ORA_JSONB, DateTimeUTC, StoredObject, PasswordHash, FernetBackend +from advanced_alchemy.types.encrypted_string import PGCryptoBackend +from advanced_alchemy.types.password_hash.argon2 import Argon2Hasher +from advanced_alchemy.types.password_hash.passlib import PasslibHasher +from advanced_alchemy.types.password_hash.pwdlib import PwdlibHasher +from pwdlib.hashers.argon2 import Argon2Hasher as PwdlibArgon2Hasher from sqlalchemy import Text # noqa: F401 if TYPE_CHECKING: @@ -26,17 +31,22 @@ sa.EncryptedString = EncryptedString sa.EncryptedText = EncryptedText sa.StoredObject = StoredObject sa.PasswordHash = PasswordHash +sa.Argon2Hasher = Argon2Hasher +sa.PasslibHasher = PasslibHasher +sa.PwdlibHasher = PwdlibHasher +sa.FernetBackend = FernetBackend +sa.PGCryptoBackend = PGCryptoBackend # revision identifiers, used by Alembic. -revision = '26022ec86f32' +revision = '65aa95e8f8cf' down_revision = None branch_labels = None depends_on = None def upgrade() -> None: - op.execute(sa.text('create EXTENSION if not EXISTS "pgcrypto"')) - op.execute(sa.text('create EXTENSION if not EXISTS "pg_trgm"')) + op.execute(sa.text('CREATE EXTENSION IF NOT EXISTS "pgcrypto"')) + op.execute(sa.text('CREATE EXTENSION IF NOT EXISTS "pg_trgm"')) with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=UserWarning) with op.get_context().autocommit_block(): diff --git a/backend/migrations/versions/2026-03-08_create_initial_tables_43bdf42a4f6c.py b/backend/migrations/versions/2026-03-14_create_initial_tables_6d72d1bbc0ee.py similarity index 72% rename from backend/migrations/versions/2026-03-08_create_initial_tables_43bdf42a4f6c.py rename to backend/migrations/versions/2026-03-14_create_initial_tables_6d72d1bbc0ee.py index 6a1212e..570b4b5 100644 --- a/backend/migrations/versions/2026-03-08_create_initial_tables_43bdf42a4f6c.py +++ b/backend/migrations/versions/2026-03-14_create_initial_tables_6d72d1bbc0ee.py @@ -1,8 +1,8 @@ """create initial tables -Revision ID: 43bdf42a4f6c -Revises: -Create Date: 2026-03-08 16:00:54.727868 +Revision ID: 6d72d1bbc0ee +Revises: 65aa95e8f8cf +Create Date: 2026-03-14 14:36:43.529584 """ @@ -38,8 +38,8 @@ sa.FernetBackend = FernetBackend sa.PGCryptoBackend = PGCryptoBackend # revision identifiers, used by Alembic. -revision = '43bdf42a4f6c' -down_revision = None +revision = '6d72d1bbc0ee' +down_revision = '65aa95e8f8cf' branch_labels = None depends_on = None @@ -61,6 +61,61 @@ def downgrade() -> None: def schema_upgrades() -> None: """schema upgrade migrations go here.""" # ### commands auto generated by Alembic - please adjust! ### + op.create_table('authors', + sa.Column('id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=False), + sa.Column('name', sa.String(), nullable=False), + sa.Column('description', sa.String(), nullable=True), + sa.Column('created_at', sa.DateTimeUTC(timezone=True), nullable=False), + sa.Column('updated_at', sa.DateTimeUTC(timezone=True), nullable=False), + sa.PrimaryKeyConstraint('id', name=op.f('pk_authors')) + ) + with op.batch_alter_table('authors', schema=None) as batch_op: + batch_op.create_index(batch_op.f('ix_authors_name'), ['name'], unique=True) + + op.create_table('book_series', + sa.Column('id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=False), + sa.Column('title', sa.String(), nullable=False), + sa.Column('created_at', sa.DateTimeUTC(timezone=True), nullable=False), + sa.Column('updated_at', sa.DateTimeUTC(timezone=True), nullable=False), + sa.PrimaryKeyConstraint('id', name=op.f('pk_book_series')) + ) + with op.batch_alter_table('book_series', schema=None) as batch_op: + batch_op.create_index(batch_op.f('ix_book_series_title'), ['title'], unique=True) + + op.create_table('libraries', + sa.Column('id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=False), + sa.Column('name', sa.String(), nullable=False), + sa.Column('root_path', sa.String(), nullable=False), + sa.Column('path_template', sa.String(), nullable=False), + sa.Column('description', sa.String(), nullable=True), + sa.Column('icon', sa.String(), nullable=False), + sa.Column('read_only', sa.Boolean(), nullable=False), + sa.Column('slug', sa.String(length=100), nullable=False), + sa.Column('created_at', sa.DateTimeUTC(timezone=True), nullable=False), + sa.Column('updated_at', sa.DateTimeUTC(timezone=True), nullable=False), + sa.PrimaryKeyConstraint('id', name=op.f('pk_libraries')), + sa.UniqueConstraint('name', name=op.f('uq_libraries_name')), + sa.UniqueConstraint('slug', name='uq_libraries_slug') + ) + with op.batch_alter_table('libraries', schema=None) as batch_op: + batch_op.create_index('ix_libraries_slug_unique', ['slug'], unique=True) + + op.create_table('publishers', + sa.Column('id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=False), + sa.Column('name', sa.String(), nullable=False), + sa.Column('description', sa.String(), nullable=True), + sa.Column('created_at', sa.DateTimeUTC(timezone=True), nullable=False), + sa.Column('updated_at', sa.DateTimeUTC(timezone=True), nullable=False), + sa.PrimaryKeyConstraint('id', name=op.f('pk_publishers')) + ) + op.create_table('tags', + sa.Column('id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=False), + sa.Column('name', sa.String(), nullable=False), + sa.PrimaryKeyConstraint('id', name=op.f('pk_tags')) + ) + with op.batch_alter_table('tags', schema=None) as batch_op: + batch_op.create_index(batch_op.f('ix_tags_name'), ['name'], unique=True) + op.create_table('users', sa.Column('id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=False), sa.Column('email', sa.String(), nullable=False), @@ -124,7 +179,8 @@ def schema_upgrades() -> None: sa.Column('position', sa.Integer(), nullable=False), sa.ForeignKeyConstraint(['author_id'], ['authors.id'], name=op.f('fk_book_author_links_author_id_authors')), sa.ForeignKeyConstraint(['book_id'], ['books.id'], name=op.f('fk_book_author_links_book_id_books'), ondelete='cascade'), - sa.PrimaryKeyConstraint('id', 'book_id', 'author_id', name=op.f('pk_book_author_links')) + sa.PrimaryKeyConstraint('id', name=op.f('pk_book_author_links')), + sa.UniqueConstraint('book_id', 'author_id', name=op.f('uq_book_author_links_book_id')) ) op.create_table('book_list_links', sa.Column('id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=False), @@ -133,7 +189,8 @@ def schema_upgrades() -> None: sa.Column('position', sa.Integer(), nullable=False), sa.ForeignKeyConstraint(['book_id'], ['books.id'], name=op.f('fk_book_list_links_book_id_books'), ondelete='cascade'), sa.ForeignKeyConstraint(['list_id'], ['book_lists.id'], name=op.f('fk_book_list_links_list_id_book_lists')), - sa.PrimaryKeyConstraint('id', 'book_id', 'list_id', name=op.f('pk_book_list_links')) + sa.PrimaryKeyConstraint('id', name=op.f('pk_book_list_links')), + sa.UniqueConstraint('book_id', 'list_id', name=op.f('uq_book_list_links_book_id')) ) op.create_table('book_progress', sa.Column('id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=False), @@ -159,7 +216,8 @@ def schema_upgrades() -> None: sa.Column('position', sa.Integer(), nullable=False), sa.ForeignKeyConstraint(['book_id'], ['books.id'], name=op.f('fk_book_tag_link_book_id_books'), ondelete='cascade'), sa.ForeignKeyConstraint(['tag_id'], ['tags.id'], name=op.f('fk_book_tag_link_tag_id_tags')), - sa.PrimaryKeyConstraint('id', 'book_id', 'tag_id', name=op.f('pk_book_tag_link')) + sa.PrimaryKeyConstraint('id', name=op.f('pk_book_tag_link')), + sa.UniqueConstraint('book_id', 'tag_id', name=op.f('uq_book_tag_link_book_id')) ) op.create_table('file_metadata', sa.Column('id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=False), @@ -177,7 +235,8 @@ def schema_upgrades() -> None: sa.Column('book_id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=False), sa.Column('value', sa.String(), nullable=False), sa.ForeignKeyConstraint(['book_id'], ['books.id'], name=op.f('fk_identifiers_book_id_books'), ondelete='cascade'), - sa.PrimaryKeyConstraint('id', 'name', 'book_id', name=op.f('pk_identifiers')) + sa.PrimaryKeyConstraint('id', name=op.f('pk_identifiers')), + sa.UniqueConstraint('name', 'book_id', name=op.f('uq_identifiers_name')) ) op.create_table('kosync_progress', sa.Column('id', sa.BigInteger().with_variant(sa.Integer(), 'sqlite'), nullable=False), @@ -213,6 +272,23 @@ def schema_downgrades() -> None: op.drop_table('books') op.drop_table('book_lists') op.drop_table('users') + with op.batch_alter_table('tags', schema=None) as batch_op: + batch_op.drop_index(batch_op.f('ix_tags_name')) + + op.drop_table('tags') + op.drop_table('publishers') + with op.batch_alter_table('libraries', schema=None) as batch_op: + batch_op.drop_index('ix_libraries_slug_unique') + + op.drop_table('libraries') + with op.batch_alter_table('book_series', schema=None) as batch_op: + batch_op.drop_index(batch_op.f('ix_book_series_title')) + + op.drop_table('book_series') + with op.batch_alter_table('authors', schema=None) as batch_op: + batch_op.drop_index(batch_op.f('ix_authors_name')) + + op.drop_table('authors') # ### end Alembic commands ### def data_upgrades() -> None: diff --git a/backend/src/chitai/database/config.py b/backend/src/chitai/database/config.py index b25f5d4..07f95c2 100644 --- a/backend/src/chitai/database/config.py +++ b/backend/src/chitai/database/config.py @@ -5,8 +5,9 @@ from advanced_alchemy.extensions.litestar import ( AsyncSessionConfig, SQLAlchemyPlugin, ) +from advanced_alchemy.base import BigIntAuditBase from sqlalchemy.ext.asyncio import create_async_engine -from chitai.database import models +from chitai.database import models # noqa: F401 # Import to register models DATABASE_URL = str(settings.postgres_uri) @@ -16,8 +17,8 @@ config = SQLAlchemyAsyncConfig( engine_instance=create_async_engine(DATABASE_URL, echo=settings.postgres_echo), session_config=session_config, before_send_handler="autocommit", - create_all=True, - + create_all=False, + metadata=BigIntAuditBase.registry.metadata, ) alchemy = SQLAlchemyPlugin(config=config)