Search code examples
pythonsqliteflasksqlalchemyflask-sqlalchemy

"Error: No such command 'db'" from "flask db init"


I am creating a Flask application on MacOS Sonoma 14.4.1 and Visual Studio Code using SQLAlchemy with sqlite3. When trying to initialize and create the tables using flask db init I get:

Usage: flask [OPTIONS] COMMAND [ARGS]...
Try 'flask --help' for help.

Error: No such command 'db'.

Project tree:

document_management_system/
|–– backend/
|   |–– pycache/
|   |   |––__init__.cpython-312.pyc
|   |–– app/
|   |   |–– pycache/
|   |       |––__init__.cpython-312.pyc
|   |   |–– __init__.py
|   |   |–– config.py
|   |   |–– models.py
|   |–– venv/
|   |   |–– . . .
|   |–– app.py
|–– frontend/
|   |–– (empty)

Output from pip list:

Package           Version
----------------- -------
alembic           1.13.1
blinker           1.7.0
click             8.1.7
Flask             3.0.3
Flask-CLI         0.4.0
Flask-Migrate     4.0.7
Flask-SQLAlchemy  3.1.1
greenlet          3.0.3
itsdangerous      2.2.0
Jinja2            3.1.3
Mako              1.3.3
MarkupSafe        2.1.5
pip               24.0
SQLAlchemy        2.0.29
typing_extensions 4.11.0
Werkzeug          3.0.2

My files:

# app.py
from flask import Flask, request, jsonify
from flask_migrate import Migrate
from app.config import Config
from app.models import db, Document

def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)

    db.init_app(app)
    migrate = Migrate(app, db)
    migrate.init_app(app, db)

    @app.route('/upload', methods=['POST'])
    def upload_document():
        id=request.form['id']
        name = request.form['name']
        category = request.form['category']
        file_path = request.form['file_path']
        document = Document(id=id, name=name, category=category, file_path=file_path)
        document.save_to_db()
        return jsonify({'message': 'File uploaded successfully'}), 200

    # Document Deletion Endpoint
    @app.route('/delete/<int:document_id>', methods=['DELETE'])
    def delete_document(document_id):
        document = Document.query.get_or_404(document_id)
        document.delete_from_db()
        return jsonify({'message': 'Document deleted successfully'}), 200

    # Search Endpoint
    @app.route('/search')
    def search_documents():
        # Implement search functionality based on query parameters
        # Example: search by document name
        name = request.args.get('name')
        if name:
            documents = Document.query.filter(Document.name.ilike(f'%{name}%')).all()
            return jsonify([document.serialize() for document in documents])
        else:
            return jsonify({'error': 'Missing query parameter "name"'}), 400

    @app.route('/')
    def hello():
        return 'Hello, World!'

    return app

if __name__ == '__main__':
    app = create_app()
    app.run(debug=True)
# config.py
import os

basedir = os.path.abspath(os.path.dirname(__file__))

class Config:
    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'db.sqlite3')
    SQLALCHEMY_TRACK_MODIFICATIONS = False
# models.py
from datetime import datetime
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class Document(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128), nullable=False)
    category = db.Column(db.String(64), nullable=False)
    file_path = db.Column(db.String(256), nullable=False)
    upload_date = db.Column(db.DateTime, nullable=False, default=datetime.now(datetime.UTC))

    # upload functionality
    def save_to_db(self):
        db.session.add(self)
        db.session.commit()

    # delete functionality
    def delete_from_db(self):
        db.session.delete(self)
        db.session.commit()

How do I complete my database setup to perform CRUD operations?

Deleting and reinstalling my venv folder and dependencies and killing the terminal as well as running flask --app flaskr init-db and pip3 install flask-migrate --upgrade did not work. I uninstalled Flask and still no change. I ran export FLASK_APP=app.py then flask shell to create it manually, but got:

Error: Failed to find application in module "backend.app". Are you sure it contains a Flask application? Maybe you wrapped it in a WSGI middleware or you are using a factory function.

Running export FLASK_APP=app.py:create_app then flask shell produces:

ModuleNotFoundError: No module named 'app'

export FLASK_APP=backend.app and export FLASK_APP=backend.app:create_app followed by flask shell both produce:

ModuleNotFoundError: No module named 'backend'


Solution

  • i started the project over again and changed the project structure. it is now

    dms/
    |–– backend/
    |   |–– flask_app/
    |   |   |–– pycache/
    |   |       |–– __init__.cpython-312.pyc
    |   |       |–– app.cpython-312.pyc
    |   |       |–– config.cpython-312.pyc
    |   |       |–– models.cpython-312.pyc
    |   |   |–– __init__.py
    |   |   |–– app.py
    |   |   |–– config.py
    |   |   |–– db.sqlite3
    |   |   |–– models.py
    |   |–– migrations/
    |   |   |–– . . .
    |   |–– venv/
    |   |   |–– . . .
    |–– frontend/
    |   |–– (empty)
    

    i ran export FLASK_APP=flask_app.app.py before running the following commands

    flask db init
    flask db migrate -m "Initial migration"
    flask db upgrade
    

    which generated the db.sqlite3 file and migrations folder for me automatically.

    i believe the structure has to do with how Flask locates the application or factory function based on the specified module or file path.

    i am not 100% on the reason but it worked out.

    the only edits made to the code were the imports in app.py due to the change in structure, they are now

    from flask_app.config import Config
    from flask_app.models import db, Document