database.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. """
  2. Database connection and initialization module.
  3. Manages SQLite database connection and table creation.
  4. """
  5. import sqlite3
  6. import os
  7. from contextlib import contextmanager
  8. from typing import Generator
  9. # Database file path
  10. DB_PATH = os.getenv("DATABASE_PATH", "annotation_platform.db")
  11. @contextmanager
  12. def get_db_connection() -> Generator[sqlite3.Connection, None, None]:
  13. """
  14. Context manager for database connections.
  15. Ensures proper connection cleanup.
  16. """
  17. conn = sqlite3.connect(DB_PATH)
  18. conn.row_factory = sqlite3.Row # Enable column access by name
  19. try:
  20. yield conn
  21. conn.commit()
  22. except Exception:
  23. conn.rollback()
  24. raise
  25. finally:
  26. conn.close()
  27. def init_database() -> None:
  28. """
  29. Initialize database and create tables if they don't exist.
  30. Creates projects, tasks, and annotations tables with proper relationships.
  31. """
  32. with get_db_connection() as conn:
  33. cursor = conn.cursor()
  34. # Enable foreign key constraints
  35. cursor.execute("PRAGMA foreign_keys = ON")
  36. # Create projects table
  37. cursor.execute("""
  38. CREATE TABLE IF NOT EXISTS projects (
  39. id TEXT PRIMARY KEY,
  40. name TEXT NOT NULL,
  41. description TEXT,
  42. config TEXT NOT NULL,
  43. created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
  44. )
  45. """)
  46. # Create tasks table
  47. cursor.execute("""
  48. CREATE TABLE IF NOT EXISTS tasks (
  49. id TEXT PRIMARY KEY,
  50. project_id TEXT NOT NULL,
  51. name TEXT NOT NULL,
  52. data TEXT NOT NULL,
  53. status TEXT DEFAULT 'pending',
  54. assigned_to TEXT,
  55. created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  56. FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
  57. )
  58. """)
  59. # Create annotations table
  60. cursor.execute("""
  61. CREATE TABLE IF NOT EXISTS annotations (
  62. id TEXT PRIMARY KEY,
  63. task_id TEXT NOT NULL,
  64. user_id TEXT NOT NULL,
  65. result TEXT NOT NULL,
  66. created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  67. updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  68. FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE
  69. )
  70. """)
  71. conn.commit()
  72. def get_db() -> sqlite3.Connection:
  73. """
  74. Get a database connection.
  75. Note: Caller is responsible for closing the connection.
  76. """
  77. conn = sqlite3.connect(DB_PATH)
  78. conn.row_factory = sqlite3.Row
  79. conn.execute("PRAGMA foreign_keys = ON")
  80. return conn