How It Works Features Pricing Blog Error Guides
Log In Start Free Trial
Flask · Python

Fix OperationalError: (sqlite3.OperationalError) no such table: user in Flask

This error means SQLAlchemy cannot find the expected database table. It typically happens when you forgot to run migrations, the database file was deleted, or the model was defined after the tables were created. Fix it by running flask db upgrade or creating tables with db.create_all() inside the app context.

Reading the Stack Trace

Traceback (most recent call last): File "/app/app/routes.py", line 15, in get_users users = User.query.all() File "/app/venv/lib/python3.12/site-packages/sqlalchemy/orm/query.py", line 2694, in all return self._iter().all() File "/app/venv/lib/python3.12/site-packages/sqlalchemy/engine/result.py", line 1710, in all return self._allrows() File "/app/venv/lib/python3.12/site-packages/sqlalchemy/engine/cursor.py", line 1348, in _exec_single_context self.dialect.do_execute(cursor, statement, parameters, context) File "/app/venv/lib/python3.12/site-packages/sqlalchemy/engine/default.py", line 736, in do_execute cursor.execute(statement, parameters) sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: user [SQL: SELECT user.id AS user_id, user.email AS user_email FROM user]

Here's what each line means:

Common Causes

1. Database migrations not run

The model exists in code but flask db upgrade was never executed, so the table was never created in the database.

# Terminal: flask run
# (never ran: flask db upgrade)

2. db.create_all() called without app context

db.create_all() was invoked outside the application context, so it silently did nothing.

from app import db
db.create_all()  # no app context, tables not created

3. Wrong database URI in config

The app points to a different database file than the one that was migrated, so the tables are missing.

# config.py
SQLALCHEMY_DATABASE_URI = 'sqlite:///prod.db'
# but migrations were run against dev.db

The Fix

Wrap db.create_all() in an app context so SQLAlchemy knows which database to target. For production apps, prefer running flask db upgrade with Alembic migrations instead of create_all().

Before (broken)
from app import db
db.create_all()  # called outside app context
After (fixed)
from app import create_app, db

app = create_app()
with app.app_context():
    db.create_all()

Testing the Fix

import pytest
from app import create_app, db
from app.models import User

@pytest.fixture
def app():
    app = create_app()
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
    app.config['TESTING'] = True
    with app.app_context():
        db.create_all()
        yield app
        db.drop_all()

def test_user_table_exists(app):
    with app.app_context():
        users = User.query.all()
        assert isinstance(users, list)

def test_can_insert_user(app):
    with app.app_context():
        user = User(email='test@example.com')
        db.session.add(user)
        db.session.commit()
        assert User.query.count() == 1

Run your tests:

pytest tests/ -v

Pushing Through CI/CD

git checkout -b fix/flask-sqlalchemy-create-tables,git add app/__init__.py migrations/,git commit -m "fix: run db.create_all inside app context and add migration",git push origin fix/flask-sqlalchemy-create-tables

Your CI config should look something like this:

name: CI
on:
  pull_request:
    branches: [main]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
          cache: 'pip'
      - run: pip install -r requirements.txt
      - run: pytest tests/ -v --tb=short
      - run: flake8 app/

The Full Manual Process: 18 Steps

Here's every step you just went through to fix this one bug:

  1. Notice the error alert or see it in your monitoring tool
  2. Open the error dashboard and read the stack trace
  3. Identify the file and line number from the stack trace
  4. Open your IDE and navigate to the file
  5. Read the surrounding code to understand context
  6. Reproduce the error locally
  7. Identify the root cause
  8. Write the fix
  9. Run the test suite locally
  10. Fix any failing tests
  11. Write new tests covering the edge case
  12. Run the full test suite again
  13. Create a new git branch
  14. Commit and push your changes
  15. Open a pull request
  16. Wait for code review
  17. Merge and deploy to production
  18. Monitor production to confirm the error is resolved

Total time: 30-60 minutes. For one bug.

Or Let bugstack Fix It in Under 2 minutes

Every step above? bugstack does it automatically.

Step 1: Install the SDK

pip install bugstack

Step 2: Initialize

import bugstack

bugstack.init(api_key=os.environ["BUGSTACK_API_KEY"])

Step 3: There is no step 3.

bugstack handles everything from here:

  1. Captures the stack trace and request context
  2. Pulls the relevant source files from your GitHub repo
  3. Analyzes the error and understands the code context
  4. Generates a minimal, verified fix
  5. Runs your existing test suite
  6. Pushes through your CI/CD pipeline
  7. Deploys to production (or opens a PR for review)

Time from error to fix deployed: Under 2 minutes.

Human involvement: zero.

Try bugstack Free →

No credit card. 5-minute setup. Cancel anytime.

Deploying the Fix (Manual Path)

  1. Run pytest locally with an in-memory SQLite database to confirm tables are created.
  2. Open a pull request with the migration and context fix.
  3. Wait for CI checks to pass on the PR.
  4. Have a teammate review and approve the PR.
  5. Merge to main and run flask db upgrade in staging before promoting to production.

Frequently Asked Questions

BugStack runs the fix through your test suite with an in-memory database, verifies all tables are created, and confirms existing migrations are not broken before marking it safe.

BugStack never pushes directly to production. Every fix goes through a pull request with full CI checks, so your team can review it before merging.

Use flask db upgrade with Alembic migrations for production apps. db.create_all() is fine for prototyping but cannot handle schema changes over time.

In development you may have run db.create_all() interactively. Production deployments start fresh and need explicit migration steps in the deploy pipeline.