You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask API调用出现404错误,寻求技术排查解决方案

问题描述

在Docker双容器(Flask + PostgreSQL)环境中运行Flask API时,所有GET、POST请求均返回404错误码。已通过PGAdmin手动创建数据库表(Flask Migrations功能失效),多次确认服务器URL配置无误,但仍无法定位问题,附上相关代码片段求助。

init.py 文件

import os
from flask_migrate import Migrate
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

def create_app(test_config=None): 
    app = Flask(__name__, instance_relative_config=True)
    app.config.from_mapping(
        SECRET_KEY='dev',
        SQLALCHEMY_DATABASE_URI = 'postgresql://postgres@localhost:5432/amazonclone',
        SQLALCHEMY_TRACK_MODIFICATIONS=False,
        SQLALCHEMY_ECHO=True
    )
    if test_config is None:
        # 加载实例配置(如果存在)
        app.config.from_pyfile('config.py', silent=True)
    else:
        # 加载测试配置
        app.config.from_mapping(test_config)

    # 确保实例文件夹存在
    try:
        os.makedirs(app.instance_path)
    except OSError:
        pass

    db = SQLAlchemy(app)
    
    migrate = Migrate(app, db)

    return app

wsgi.py 文件

from src import create_app

app = create_app()

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5000)

API路由文件(部分内容)

from flash import Flask, jsonify, request, abort  # 注意:此处有拼写错误
from bookModel import Book, BookSchema
from clothingModel import Clothing, ClothingSchema
from movieModel import Movie, MovieSchema
from home_garden import HomeAndGarden, HomeAndGardenSchema
from electronic import Electronic, ElectronicSchema
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow

app = Flask(__name__)

app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres@localhost:5432/amazonclone'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
ma = Marshmallow(app)

# Book路由
@app.route('/books', methods=['POST'])
def add_book():
    # 检查请求体是否包含所有必填字段
    if not all(key in request.json for key in ['genre', 'author', 'style', 'name']):
        abort(400, 'Missing required keys in Json payload')

    # 从请求体获取数据
    genre = request.json['genre']
    author = request.json['author']
    style = request.json['style']
    name = request.json['name']

    # 创建新Book对象并添加到数据库
    my_books = Book(genre, author, style, name)
    db.session.add(my_books)
    db.session.commit()

    # 序列化并返回新对象
    return jsonify(Book.dump(my_books)), 201
问题分析与修复方案

核心问题:路由未注册到运行的Flask实例

当前代码中,路由文件新建了一个独立的Flask实例,而wsgi.py中运行的是create_app()创建的另一个实例——两个实例完全独立,导致定义的路由根本没有被加载到正在运行的API服务中,这是所有请求返回404的直接原因。

其他关键问题

  • Docker环境下数据库地址错误:容器内的localhost指向Flask容器本身,而非PostgreSQL容器,需要用PostgreSQL容器的名称作为主机名(例如postgres,需与docker-compose.yml中的服务名一致)。
  • Migrations失效:create_app()中初始化了Migrate,但未导入任何模型类,导致Migrate无法识别数据库模型,无法生成迁移文件。
  • 导入拼写错误:路由文件中from flash import Flask是错误拼写,应为from flask import Flask,会直接导致路由文件无法正常加载。

具体修复步骤

1. 统一Flask实例,用蓝图管理路由

这是Flask项目组织路由的标准方式,避免多实例冲突:

  • 修改路由文件,删除独立的Flask、db、ma初始化代码,改用蓝图(Blueprint):
from flask import Blueprint, jsonify, request, abort  # 修正导入拼写
from bookModel import Book, BookSchema
# 其他模型导入保持不变
from src import db  # 从create_app的实例中导入db

# 创建蓝图
bp = Blueprint('products', __name__)

# Book路由
@bp.route('/books', methods=['POST'])
def add_book():
    if not all(key in request.json for key in ['genre', 'author', 'style', 'name']):
        abort(400, 'Json payload缺少必填字段')
    
    genre = request.json['genre']
    author = request.json['author']
    style = request.json['style']
    name = request.json['name']

    my_books = Book(genre, author, style, name)
    db.session.add(my_books)
    db.session.commit()

    return jsonify(BookSchema().dump(my_books)), 201
  • 在__init__.py的create_app函数末尾注册蓝图:
def create_app(test_config=None):
    # ... 原有代码保持不变 ...

    db = SQLAlchemy(app)
    # 导入所有模型类(修复Migrations失效)
    from .bookModel import Book
    from .clothingModel import Clothing
    from .movieModel import Movie
    from .home_garden import HomeAndGarden
    from .electronic import Electronic
    
    migrate = Migrate(app, db)

    # 注册路由蓝图
    from .routes import bp as products_bp
    app.register_blueprint(products_bp)

    return app

2. 修正Docker环境下的数据库连接地址

将__init__.py中的SQLALCHEMY_DATABASE_URI修改为:

SQLALCHEMY_DATABASE_URI = 'postgresql://postgres@postgres:5432/amazonclone'

注:postgres为PostgreSQL容器的服务名称,需与你的docker-compose.yml中定义的服务名一致。

3. 验证路由加载

启动服务后,可以通过以下代码在wsgi.py中打印所有注册的路由,确认路由是否被正确加载:

from src import create_app

app = create_app()

# 打印所有路由
print("Registered Routes:")
for rule in app.url_map.iter_rules():
    print(f"{rule.methods} {rule.rule}")

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5000)

内容的提问来源于stack exchange,提问作者Babit56

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 16:24:54