fix: 修复连接池泄漏和绕过问题

- 修复 analysis.py ai_analyze_stream 中 _put_db(conn) 拼写错误导致连接泄漏
- 将 analysis.py 6处 psycopg2.connect() 替换为 get_db()/put_db() 统一连接池管理
- 将 admin.py 2处 psycopg2.connect() 替换为 get_db()/put_db() 统一连接池管理
- 移除不再需要的 import psycopg2 和 from config import Config
This commit is contained in:
freedakgmail
2026-07-22 07:27:58 +08:00
parent 40ce519188
commit 4e35ab852f
2 changed files with 27 additions and 53 deletions
+6 -13
View File
@@ -753,13 +753,9 @@ def trigger_kline_sync():
def kline_sync_status():
"""管理员查询K线同步状态"""
try:
import psycopg2
from config import Config
conn = psycopg2.connect(
host=Config.DB_HOST, port=Config.DB_PORT,
dbname=Config.DB_NAME, user=Config.DB_USER, password=Config.DB_PASSWORD,
)
conn = get_db()
if not conn:
return jsonify({'success': False, 'error': '数据库连接失败'}), 500
cur = conn.cursor()
# K线数据统计
@@ -1282,13 +1278,10 @@ def admin_scan_status():
"""管理员查询扫描进度"""
try:
from datetime import datetime
import psycopg2
from config import Config
conn = psycopg2.connect(
host=Config.DB_HOST, port=Config.DB_PORT,
dbname=Config.DB_NAME, user=Config.DB_USER, password=Config.DB_PASSWORD,
)
conn = get_db()
if not conn:
return jsonify({'success': False, 'error': '数据库连接失败'}), 500
cur = conn.cursor()
scan_date = datetime.now().strftime('%Y-%m-%d')
+21 -40
View File
@@ -15,7 +15,8 @@ from services.stock_algorithms import (
)
from db import (
login_required, get_current_user_id,
db_get_alerts_cache, db_save_alerts_cache
db_get_alerts_cache, db_save_alerts_cache,
get_db, put_db
)
bp = Blueprint('analysis', __name__, url_prefix='/api')
@@ -399,7 +400,7 @@ def ai_analyze_stream(stock_code):
_cur.execute("INSERT INTO ai_call_log (user_id, stock_code, stock_name) VALUES (%s, %s, %s)",
(_uid, stock_code, stock_name))
_conn.commit()
_put_db(conn)
put_db(_conn)
except Exception:
pass
@@ -544,10 +545,8 @@ def batch_technical_signals():
"""批量检测技术交易信号 — 优先从 stock_signal_scan 读取(与提醒一致),无记录时实时计算"""
try:
import pandas as pd
import psycopg2
from psycopg2.extras import RealDictCursor
from services.signal_detector import detect_all_signals
from config import Config
data = request.get_json()
codes = data.get('codes', [])
@@ -566,10 +565,9 @@ def batch_technical_signals():
change_map = {}
scan_map = {}
try:
conn = psycopg2.connect(
host=Config.DB_HOST, port=Config.DB_PORT,
dbname=Config.DB_NAME, user=Config.DB_USER, password=Config.DB_PASSWORD,
)
conn = get_db()
if not conn:
raise Exception('数据库连接失败')
cur = conn.cursor(cursor_factory=RealDictCursor)
placeholders = ','.join(['%s'] * len(codes))
@@ -675,9 +673,6 @@ def batch_technical_signals():
def get_scan_results():
"""查询全量扫描结果"""
try:
import psycopg2
from config import Config
scan_date = request.args.get('date', datetime.now().strftime('%Y-%m-%d'))
min_triggered = int(request.args.get('min_triggered', 0))
signal_type = request.args.get('signal_type', '')
@@ -689,10 +684,9 @@ def get_scan_results():
holding_set = set(c.strip() for c in holding_codes_str.split(',') if c.strip())
recommend_text = (request.args.get('recommend_text') or '').strip()
conn = psycopg2.connect(
host=Config.DB_HOST, port=Config.DB_PORT,
dbname=Config.DB_NAME, user=Config.DB_USER, password=Config.DB_PASSWORD,
)
conn = get_db()
if not conn:
return jsonify({'success': False, 'error': '数据库连接失败'}), 500
cur = conn.cursor()
# 检查请求日期是否有数据,如果没有则自动回退到最近可用的扫描日期
@@ -955,9 +949,7 @@ def _compute_recommend(signal_status, indicators, triggered_count, is_holding):
@bp.route('/signal_alerts', methods=['POST'])
def signal_alerts():
"""基于信号扫描结果生成买入/卖出/观望提醒(与扫描结果共用 _compute_recommend"""
import psycopg2
from psycopg2.extras import RealDictCursor
from config import Config
try:
data = request.get_json() or {}
@@ -968,10 +960,9 @@ def signal_alerts():
if not stock_codes:
return jsonify({'success': True, 'results': []})
conn = psycopg2.connect(
host=Config.DB_HOST, port=Config.DB_PORT,
dbname=Config.DB_NAME, user=Config.DB_USER, password=Config.DB_PASSWORD,
)
conn = get_db()
if not conn:
return jsonify({'success': False, 'error': '数据库连接失败'}), 500
cur = conn.cursor(cursor_factory=RealDictCursor)
# 优先今天的扫描数据,无则回退到最近可用日期
@@ -1127,13 +1118,9 @@ def get_stock_score_detail(code):
def get_scan_status():
"""查询扫描进度"""
try:
import psycopg2
from config import Config
conn = psycopg2.connect(
host=Config.DB_HOST, port=Config.DB_PORT,
dbname=Config.DB_NAME, user=Config.DB_USER, password=Config.DB_PASSWORD,
)
conn = get_db()
if not conn:
return jsonify({'success': False, 'error': '数据库连接失败'}), 500
cur = conn.cursor()
scan_date = datetime.now().strftime('%Y-%m-%d')
@@ -1210,18 +1197,15 @@ def start_full_scan():
def get_scan_strategy():
"""基于体系最强战法,给出分梯队买卖建议。与全景扫描推荐共用 _compute_recommend,算法一致。"""
try:
import psycopg2
from psycopg2.extras import RealDictCursor
from config import Config
scan_date = request.args.get('date', datetime.now().strftime('%Y-%m-%d'))
holding_codes_str = request.args.get('holding_codes', '')
holding_set = set(c.strip() for c in holding_codes_str.split(',') if c.strip())
conn = psycopg2.connect(
host=Config.DB_HOST, port=Config.DB_PORT,
dbname=Config.DB_NAME, user=Config.DB_USER, password=Config.DB_PASSWORD,
)
conn = get_db()
if not conn:
return jsonify({'success': False, 'error': '数据库连接失败'}), 500
cur = conn.cursor(cursor_factory=RealDictCursor)
# 如果前端未指定日期,且当天无数据,自动回退到最近扫描日期
@@ -1345,19 +1329,16 @@ def get_bull_stocks():
stage: 可选,筛选特定阶段(1-5)
holdingStocks: 可选,持仓代码逗号分隔
"""
import psycopg2
from psycopg2.extras import RealDictCursor
from config import Config
try:
stage_filter = request.args.get('stage', type=int, default=0)
holding_str = request.args.get('holdingStocks', '')
holding_codes = set(holding_str.split(',')) if holding_str else set()
conn = psycopg2.connect(
host=Config.DB_HOST, port=Config.DB_PORT,
dbname=Config.DB_NAME, user=Config.DB_USER, password=Config.DB_PASSWORD,
)
conn = get_db()
if not conn:
return jsonify({'success': False, 'error': '数据库连接失败'}), 500
cur = conn.cursor(cursor_factory=RealDictCursor)
# 获取最近一次扫描数据(过滤退市/ST)