Skip to content

feat(database): Database Connection Module and Seed Data (#11) - #20

Merged
deserat merged 2 commits into
developfrom
feature/EPIC-2-3-database-connection-module
Jan 23, 2026
Merged

feat(database): Database Connection Module and Seed Data (#11)#20
deserat merged 2 commits into
developfrom
feature/EPIC-2-3-database-connection-module

Conversation

@deserat

@deserat deserat commented Jan 22, 2026

Copy link
Copy Markdown
Owner

Summary

Implements production-ready database connection management with connection pooling, retry logic, and health checks, along with an idempotent seed data script for development environments.

Resolves: #11
Parent Epic: EPIC-2 - PostgreSQL Database with pgvector

Changes

Database Connection Module (app/db/session.py)

  • ✅ Connection pooling with QueuePool (pool_size=5, max_overflow=10, pool_pre_ping, pool_recycle=3600)
  • ✅ Session factory with autocommit=False, autoflush=False
  • ✅ Context manager (get_db_session) for safe transaction handling
  • ✅ Health check function (check_database_health)
  • ✅ Retry logic with exponential backoff using tenacity library

Seed Data Script (migrations/seed_data.py)

  • ✅ Creates development user (dev@noosphere.local)
  • ✅ Creates classification prompt v1 with comprehensive category descriptions
  • ✅ Creates sample items across 4 categories:
    • Admin: "Setup Development Environment"
    • Ideas: "Feature Idea: Multi-user Support"
    • People: "Contact: Jane Doe (Design Consultant)"
    • Projects: "Project: Noosphere Knowledge System"
  • ✅ Fully idempotent - safe to run multiple times
  • ✅ Embedding placeholders ([0.0] * 1536) for all items

Testing

  • 10 tests for session module covering:

    • Engine creation and session factory
    • Context manager (success, rollback, cleanup)
    • Health check (success and failure scenarios)
    • Retry logic (immediate success, eventual success, max attempts)
  • 9 tests for seed data script covering:

    • Data creation (user, prompt, items)
    • Idempotency (running multiple times)
    • Skipping existing data
    • Embedding validation
    • Error handling
  • 74 total tests passing (19 new + 55 existing)

  • ✅ Transaction isolation working correctly

Dependencies

  • Added tenacity>=8.2.3,<9.0.0 for retry logic with exponential backoff

Quality Checks

  • ruff format: All files formatted
  • ruff check: No linting violations
  • pyright: No type errors
  • pytest: All 74 tests passing

Files Changed

Added:

  • api-service/app/db/session.py (108 lines)
  • api-service/migrations/seed_data.py (142 lines)
  • api-service/tests/db/__init__.py
  • api-service/tests/db/test_session.py (112 lines)
  • api-service/tests/test_seed_data.py (142 lines)

Modified:

  • api-service/requirements.txt (added tenacity)
  • api-service/app/db/__init__.py (exported session functions)

Usage

Running Seed Data

# From api-service directory
python -m migrations.seed_data

Using Connection Module

from app.db.session import get_db_session, check_database_health

# Safe session handling with automatic commit/rollback
with get_db_session() as session:
    user = session.query(User).first()

# Health check
if check_database_health():
    print("Database is healthy")

Test Plan

  • All 74 tests passing
  • Clean test database verified
  • Seed script creates all required data
  • Idempotency verified (ran seed script twice)
  • Connection pooling configured correctly
  • Health check works for both success and failure
  • Retry logic handles transient failures

Related Issues

🤖 Generated with Claude Code

Implements production-ready database connection management with connection
pooling, retry logic, health checks, and an idempotent seed data script for
development environments.

**Database Connection Module (app/db/session.py):**
- Connection pooling with QueuePool (pool_size=5, max_overflow=10)
- Session factory with autocommit=False, autoflush=False
- Context manager (get_db_session) for safe session handling
- Health check function (check_database_health)
- Retry logic with exponential backoff using tenacity

**Seed Data Script (migrations/seed_data.py):**
- Creates development user (dev@noosphere.local)
- Creates classification prompt v1
- Creates sample items across 4 categories (Admin, Ideas, People, Projects)
- Fully idempotent - safe to run multiple times
- Accepts optional session parameter for testing

**Testing:**
- 10 tests for session module (connection, context manager, health check, retry)
- 9 tests for seed data script (creation, idempotency, data validation)
- All tests passing with transaction isolation
- 74 total tests passing (19 new + 55 existing)

**Dependencies:**
- Added tenacity>=8.2.3,<9.0.0 for retry logic

**Files Added:**
- api-service/app/db/session.py
- api-service/migrations/seed_data.py
- api-service/tests/db/__init__.py
- api-service/tests/db/test_session.py
- api-service/tests/test_seed_data.py

**Files Modified:**
- api-service/requirements.txt (added tenacity)
- api-service/app/db/__init__.py (exported session functions)

**Quality Checks:**
✅ ruff format - all files formatted
✅ ruff check - no violations
✅ pyright - no type errors
✅ pytest - all 74 tests passing

Closes #11

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@github-actions github-actions Bot added service/api-service FastAPI Python backend service/database PostgreSQL schema/migrations labels Jan 22, 2026
@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @deserat, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the api-service's database capabilities by introducing a robust and resilient connection management system, alongside a convenient and idempotent seed data utility for development. These changes lay a solid foundation for reliable data access and streamline the setup of local development environments, ensuring that the application can interact with the database efficiently and gracefully handle transient connection issues.

Highlights

  • Robust Database Connection Module: Implemented a production-ready database connection module (app/db/session.py) featuring connection pooling (QueuePool), a session factory with autocommit/autoflush disabled, a context manager (get_db_session) for safe transaction handling (commit on success, rollback on error, always close), a database health check function, and retry logic with exponential backoff using the tenacity library.
  • Idempotent Seed Data Script: Introduced a new seed data script (migrations/seed_data.py) designed for development environments. This script creates a default development user, a classification prompt (v1) with comprehensive category descriptions, and sample items across various categories. The script is fully idempotent, ensuring it can be run multiple times without duplicating data, and includes placeholder embeddings for all items.
  • Comprehensive Testing: Added extensive unit tests for both the new database session module (10 tests) and the seed data script (9 tests). These tests cover engine creation, session factory behavior, context manager functionality (success, rollback, cleanup), health check scenarios, retry logic (immediate success, eventual success, max attempts), data creation, idempotency, skipping existing data, embedding validation, and error handling. All 74 total tests (19 new + 55 existing) are passing.
  • Dependency Update: Added the tenacity library (tenacity>=8.2.3,<9.0.0) to requirements.txt to enable robust retry mechanisms for database connection attempts.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a robust database connection module and a helpful seed data script. The implementation is solid, with good use of connection pooling, retry logic with tenacity, and a well-structured, idempotent seeder. The accompanying tests are thorough and cover success, failure, and edge cases effectively.

My review includes a few suggestions to improve maintainability and correctness:

  • Refining the public API of the db module.
  • Using more specific exception handling.
  • Correcting a docstring for accuracy.
  • Removing a magic number for the embedding dimension.
  • Fixing a couple of minor issues in the tests related to imports.

Overall, this is a high-quality contribution that sets a strong foundation for database interactions in the application.

Comment thread api-service/tests/db/test_session.py Outdated
# Session should be closed after exiting context
# Verify by trying to execute a query, which should fail
with pytest.raises((InvalidRequestError, Exception)):
db_session_obj.execute(text("SELECT 1"))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The text function from SQLAlchemy is used here, but it has not been imported in this file. This will cause a NameError when the test runs. Please add from sqlalchemy import text to the imports at the top of the file.

Comment on lines +26 to +33
__all__ = [
"_import_models",
"engine",
"SessionLocal",
"get_db_session",
"check_database_health",
"connect_with_retry",
]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The function _import_models is prefixed with an underscore, indicating it's intended for internal use (specifically by Alembic, as noted in app/db/base.py). Exporting it in __all__ makes it part of the public API of the app.db package, which is misleading. It should be removed from __all__ to maintain a clean public interface.

__all__ = [
    "engine",
    "SessionLocal",
    "get_db_session",
    "check_database_health",
    "connect_with_retry",
]

Comment thread api-service/app/db/session.py Outdated
Comment thread api-service/app/db/session.py Outdated
Comment thread api-service/migrations/seed_data.py Outdated
Comment thread api-service/tests/db/test_session.py Outdated
@deserat

deserat commented Jan 23, 2026

Copy link
Copy Markdown
Owner Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a robust database connection module and a seed data script, which are great additions. The implementation is solid, with connection pooling, retry logic, and comprehensive tests.

My review focuses on a few areas for improvement:

  • Configuration Management: Moving load_dotenv() out of the session module to the application entry point for better control.
  • Code Maintainability: Refactoring magic numbers into constants and improving module-level exports (__all__).
  • Test Quality: Making tests more specific and removing redundancy.
  • Clarity: Improving docstrings and logging for better developer experience and debuggability.

Overall, this is a high-quality contribution. The suggested changes are mostly aimed at improving long-term maintainability and adhering to best practices.

from unittest.mock import Mock, patch

import pytest
from sqlalchemy.exc import OperationalError

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The text function is used in test_get_db_session_always_closes but is not imported, which will lead to a NameError. It should be imported from sqlalchemy.

Suggested change
from sqlalchemy.exc import OperationalError
from sqlalchemy import text
from sqlalchemy.exc import OperationalError

Comment thread api-service/app/db/session.py Outdated
Comment on lines +6 to 11
Usage:
from app.db.session import get_db_session, check_database_health

with get_db_session() as session:
users = session.query(User).all()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The usage example in the docstring is a bit misleading. It shows importing from app.db.session, but since this is the app.db package's __init__.py, the example should demonstrate usage by importing from app.db. Also, the User model is used without being imported, which could be confusing. It would be clearer to either show the import or use a more generic example that doesn't require a model.

Suggested change
Usage:
from app.db.session import get_db_session, check_database_health
with get_db_session() as session:
users = session.query(User).all()
Usage:
from app.db import get_db_session
from app.models.user import User
with get_db_session() as session:
users = session.query(User).all()

Comment on lines +26 to +33
__all__ = [
"_import_models",
"engine",
"SessionLocal",
"get_db_session",
"check_database_health",
"connect_with_retry",
]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The __all__ list exports _import_models, which is prefixed with an underscore, suggesting it's for internal use. Typically, such internal functions shouldn't be part of a module's public API. It's also good practice to keep the __all__ list sorted alphabetically for better readability and maintenance.

I suggest removing _import_models and sorting the list.

__all__ = [
    "SessionLocal",
    "check_database_health",
    "connect_with_retry",
    "engine",
    "get_db_session",
]

Comment thread api-service/app/db/session.py Outdated
Comment thread api-service/app/db/session.py Outdated
Comment thread api-service/migrations/seed_data.py Outdated
Comment thread api-service/migrations/seed_data.py Outdated
Comment thread api-service/tests/db/test_session.py Outdated
Comment thread api-service/tests/test_seed_data.py Outdated
Addresses all feedback from Gemini Code Assist code review:

**Critical/High Priority:**
- Add missing text import in test_session.py (NameError fix)
- Remove load_dotenv() from session.py (better architecture)
  Environment should be loaded at application entry point
- Move uuid import to top of file (PEP 8)

**Exception Handling:**
- Use specific OperationalError instead of generic Exception
- Add logging to check_database_health() for debugging
- Improve test_get_db_session_always_closes to verify close() is called

**Documentation:**
- Fix connect_with_retry docstring (accurate wait times: 1s, 2s)
- Fix __init__.py docstring example (correct import path and User import)

**API Design:**
- Remove _import_models from public API (__all__)
- Sort __all__ alphabetically for maintainability

**Code Quality:**
- Extract embedding dimension to named constant (EMBEDDING_DIMENSION = 1536)
- Use constant in Item model, seed_data.py, and tests
- Remove sys.path manipulation from seed_data.py
- Remove redundant test (test_seed_data_handles_errors_gracefully)

**Testing:**
- 73 tests passing (removed 1 redundant test)
- All quality checks passing (ruff, pyright)
- Seed script verified working

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@deserat
deserat merged commit f8f845d into develop Jan 23, 2026
1 check passed
@deserat
deserat deleted the feature/EPIC-2-3-database-connection-module branch January 23, 2026 02:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

service/api-service FastAPI Python backend service/database PostgreSQL schema/migrations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant