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

React调用Flask接口时出现psycopg2递归连接错误

解决psycopg2.ProgrammingError: 连接无法递归进入的问题

一、后端核心问题与修复

错误根源是全局数据库连接在多请求并发时的冲突:Flask默认多线程运行,代码中使用全局connection对象,当多个前端请求同时到达时,多线程会尝试递归进入同一个连接的上下文(with connection:),触发psycopg2的递归连接限制。

修复方案1:每次请求创建独立连接

将数据库连接的创建和销毁放在视图函数内部,确保每个请求使用独立连接:

import psycopg2
from flask import Flask

app = Flask(__name__)

PLOT_PROJECT_CHECK = "SELECT ..."  # 替换为你的查询语句
PLOT_PROJECT_DEACTIVATE = "UPDATE ..."  # 替换为你的更新语句

@app.get("/api/plot-project/<int:plot_id>/<int:project_id>")
def check_and_deactivate(plot_id, project_id):
    # 每次请求创建新连接
    conn = psycopg2.connect(
        user="你的数据库用户名",
        password="你的数据库密码",
        host="127.0.0.1",
        port="5432",
        database="你的数据库名"
    )
    try:
        with conn.cursor() as cursor:
            cursor.execute(PLOT_PROJECT_CHECK, (plot_id, project_id))
            data = cursor.fetchall()
            if len(data) == 0:
                return "No data found", 404
            removed = data.pop(0)
            if len(data) > 1:
                for row in data:
                    print(row[0])
                    cursor.execute(PLOT_PROJECT_DEACTIVATE, ('deleted', row[0], plot_id, project_id))
        # 提交事务
        conn.commit()
        return { "Remain": removed }, 200   
    finally:
        # 确保连接关闭
        conn.close()

修复方案2:使用连接池(推荐)

频繁创建销毁连接会影响性能,用psycopg2的连接池复用连接,同时保证线程安全:

import psycopg2
from psycopg2 import pool
from flask import Flask

app = Flask(__name__)

# 初始化连接池(启动时创建)
connection_pool = pool.SimpleConnectionPool(
    minconn=1,
    maxconn=10,
    user="你的数据库用户名",
    password="你的数据库密码",
    host="127.0.0.1",
    port="5432",
    database="你的数据库名"
)

PLOT_PROJECT_CHECK = "SELECT ..."
PLOT_PROJECT_DEACTIVATE = "UPDATE ..."

@app.get("/api/plot-project/<int:plot_id>/<int:project_id>")
def check_and_deactivate(plot_id, project_id):
    # 从连接池获取连接
    conn = connection_pool.getconn()
    try:
        with conn.cursor() as cursor:
            cursor.execute(PLOT_PROJECT_CHECK, (plot_id, project_id))
            data = cursor.fetchall()
            if len(data) == 0:
                return "No data found", 404
            removed = data.pop(0)
            if len(data) > 1:
                for row in data:
                    print(row[0])
                    cursor.execute(PLOT_PROJECT_DEACTIVATE, ('deleted', row[0], plot_id, project_id))
        conn.commit()
        return { "Remain": removed }, 200   
    finally:
        # 将连接归还到池
        connection_pool.putconn(conn)

二、前端问题与优化

1. 并行请求加剧后端压力

原代码中forEach搭配async/await不会串行执行请求,而是同时发起所有请求,加剧连接冲突。改成for...of实现串行请求:

const handleGet = async () => {
  for (const item of data) {
    await getData(item.plotID, item.projectID);
  }
}

2. no-cors模式导致无法解析响应

mode: 'no-cors'会让fetch返回不透明响应,无法解析JSON。后端配置CORS后,去掉该模式:

const getData = async (plotID, projectID) => { 
  try {
    const response = await fetch(`http://127.0.0.1:5000/api/plot-project/${plotID}/${projectID}`, {  
      method: 'GET',  
      headers: {    
        'Content-Type': 'application/json',    
        'Authorization': `Bearer ${token}`  
      }
    });
    if (!response.ok) {
      throw new Error(`HTTP错误:${response.status}`);
    }
    const responseData = await response.json();
    console.log('mapping', plotID, "to", projectID);
    console.log('request succeeded with JSON response', responseData);
  } catch (error) {
    console.log('mapping', plotID, "to", projectID);
    console.log('请求失败', error);
  }
}

3. 后端配置CORS

安装Flask-CORS扩展解决跨域问题:

pip install flask-cors
from flask_cors import CORS

app = Flask(__name__)
CORS(app)  # 生产环境可指定允许的源,如CORS(app, origins="http://localhost:3000")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 03:10:25