-
Notifications
You must be signed in to change notification settings - Fork 594
feat(folder-ui): add bulk AI tagging controls, smart sorting, and pro… #787
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
VasuS609
wants to merge
2
commits into
AOSSIE-Org:main
Choose a base branch
from
VasuS609:feat/bulk-ai-tagging
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| # Database Migration Guide | ||
|
|
||
| ## Quick Fix for "no such column" Errors | ||
|
|
||
| If you see errors like: | ||
| ``` | ||
| [BACKEND] | ERROR | Error getting all images: no such column: i.isFavourite | ||
| ``` | ||
|
|
||
| ### Solution 1: Run Migration Script (Recommended) | ||
| This preserves your existing data: | ||
|
|
||
| ```bash | ||
| cd backend | ||
| python migrate_database.py | ||
| ``` | ||
|
|
||
| ### Solution 2: Reset Database (Nuclear Option) | ||
| ⚠️ **Warning: This deletes all your data!** | ||
|
|
||
| ```bash | ||
| cd backend | ||
| python reset_database.py | ||
| ``` | ||
|
|
||
| Then restart the backend server. | ||
|
|
||
| ## How Migrations Work | ||
|
|
||
| The application now includes automatic schema migrations: | ||
|
|
||
| 1. **Automatic Migration**: When the app starts, it checks if required columns exist | ||
| 2. **Zero Downtime**: Migrations run transparently without data loss | ||
| 3. **Safe Defaults**: New columns are added with sensible default values | ||
|
|
||
| ## Manual Migration | ||
|
|
||
| If you need to run migrations manually: | ||
|
|
||
| ```python | ||
| from app.database.images import db_create_images_table | ||
|
|
||
| # This will create tables and run any necessary migrations | ||
| db_create_images_table() | ||
| ``` | ||
|
|
||
| ## Adding New Columns (For Developers) | ||
|
|
||
| When adding new database columns: | ||
|
|
||
| 1. **Update the CREATE TABLE statement** in the respective database file | ||
| 2. **Add migration logic** to the `_check_and_migrate_schema()` function | ||
| 3. **Test the migration** on a copy of the production database | ||
| 4. **Document the change** in this file | ||
|
|
||
| Example: | ||
| ```python | ||
| def _check_and_migrate_schema(conn: sqlite3.Connection) -> None: | ||
| cursor = conn.cursor() | ||
| cursor.execute("PRAGMA table_info(images)") | ||
| columns = [col[1] for col in cursor.fetchall()] | ||
|
|
||
| # Add new column if it doesn't exist | ||
| if "newColumn" not in columns: | ||
| logger.info("Adding 'newColumn' to images table") | ||
| cursor.execute("ALTER TABLE images ADD COLUMN newColumn TEXT DEFAULT ''") | ||
| conn.commit() | ||
| ``` | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Migration Fails | ||
| - Check database file permissions | ||
| - Ensure no other process is locking the database | ||
| - Check available disk space | ||
|
|
||
| ### Column Still Missing After Migration | ||
| - Restart the backend server | ||
| - Check logs for migration success message | ||
| - Verify the database file path in settings | ||
|
|
||
| ### Database is Corrupted | ||
| If migration fails due to corruption: | ||
| 1. Backup your database file (`*.db`) | ||
| 2. Try SQLite recovery tools | ||
| 3. As last resort, use `reset_database.py` (data loss!) | ||
|
|
||
| ## Database Schema Version | ||
|
|
||
| Current schema includes: | ||
| - ✅ `images.isFavourite` (added: Dec 2025) | ||
| - ✅ `images.isTagged` | ||
| - ✅ `images.metadata` | ||
| - ✅ `image_classes` junction table | ||
|
|
||
| ## Future Migrations | ||
|
|
||
| Planned schema changes: | ||
| - [ ] Add `rating` column for star ratings (1-5) | ||
| - [ ] Add `dateModified` column for edit tracking | ||
| - [ ] Add `albums` table for album management |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| """ | ||
| Database Migration Script | ||
| Adds the isFavourite column to existing images table if it doesn't exist. | ||
| """ | ||
|
|
||
| import sqlite3 | ||
| from app.config.settings import DATABASE_PATH | ||
| from app.logging.setup_logging import get_logger | ||
|
|
||
| logger = get_logger(__name__) | ||
|
|
||
|
|
||
| def check_column_exists(cursor, table_name: str, column_name: str) -> bool: | ||
| """Check if a column exists in a table.""" | ||
| cursor.execute(f"PRAGMA table_info({table_name})") | ||
| columns = [col[1] for col in cursor.fetchall()] | ||
| return column_name in columns | ||
|
|
||
|
|
||
| def migrate_database(): | ||
| """Add missing columns to the images table.""" | ||
| try: | ||
| conn = sqlite3.connect(DATABASE_PATH) | ||
| cursor = conn.cursor() | ||
|
|
||
| # Check if isFavourite column exists | ||
| if not check_column_exists(cursor, "images", "isFavourite"): | ||
| logger.info("Adding 'isFavourite' column to images table...") | ||
| cursor.execute( | ||
| """ | ||
| ALTER TABLE images | ||
| ADD COLUMN isFavourite BOOLEAN DEFAULT 0 | ||
| """ | ||
| ) | ||
| conn.commit() | ||
| logger.info("✓ Successfully added 'isFavourite' column") | ||
| else: | ||
| logger.info("✓ 'isFavourite' column already exists") | ||
|
|
||
| conn.close() | ||
| print("\n✅ Database migration completed successfully!") | ||
|
|
||
| except sqlite3.Error as e: | ||
| logger.error(f"Database migration failed: {e}") | ||
| print(f"\n❌ Migration failed: {e}") | ||
| raise | ||
| except Exception as e: | ||
| logger.error(f"Unexpected error during migration: {e}") | ||
| print(f"\n❌ Unexpected error: {e}") | ||
| raise | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| print("Starting database migration...") | ||
| migrate_database() | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Resource leak: database connection not closed on exception.
If an exception occurs before line 40, the database connection remains open. This could lead to connection leaks and database locks.
Apply this diff to use a context manager:
def migrate_database(): """Add missing columns to the images table.""" + conn = None try: conn = sqlite3.connect(DATABASE_PATH) cursor = conn.cursor() # Check if isFavourite column exists if not check_column_exists(cursor, "images", "isFavourite"): logger.info("Adding 'isFavourite' column to images table...") cursor.execute( """ ALTER TABLE images ADD COLUMN isFavourite BOOLEAN DEFAULT 0 """ ) conn.commit() logger.info("✓ Successfully added 'isFavourite' column") else: logger.info("✓ 'isFavourite' column already exists") - conn.close() print("\n✅ Database migration completed successfully!") except sqlite3.Error as e: logger.error(f"Database migration failed: {e}") print(f"\n❌ Migration failed: {e}") raise except Exception as e: logger.error(f"Unexpected error during migration: {e}") print(f"\n❌ Unexpected error: {e}") raise + finally: + if conn: + conn.close()🤖 Prompt for AI Agents