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:
@@ -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')
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user