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():
|
def kline_sync_status():
|
||||||
"""管理员查询K线同步状态"""
|
"""管理员查询K线同步状态"""
|
||||||
try:
|
try:
|
||||||
import psycopg2
|
conn = get_db()
|
||||||
from config import Config
|
if not conn:
|
||||||
|
return jsonify({'success': False, 'error': '数据库连接失败'}), 500
|
||||||
conn = psycopg2.connect(
|
|
||||||
host=Config.DB_HOST, port=Config.DB_PORT,
|
|
||||||
dbname=Config.DB_NAME, user=Config.DB_USER, password=Config.DB_PASSWORD,
|
|
||||||
)
|
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
|
|
||||||
# K线数据统计
|
# K线数据统计
|
||||||
@@ -1282,13 +1278,10 @@ def admin_scan_status():
|
|||||||
"""管理员查询扫描进度"""
|
"""管理员查询扫描进度"""
|
||||||
try:
|
try:
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import psycopg2
|
|
||||||
from config import Config
|
|
||||||
|
|
||||||
conn = psycopg2.connect(
|
conn = get_db()
|
||||||
host=Config.DB_HOST, port=Config.DB_PORT,
|
if not conn:
|
||||||
dbname=Config.DB_NAME, user=Config.DB_USER, password=Config.DB_PASSWORD,
|
return jsonify({'success': False, 'error': '数据库连接失败'}), 500
|
||||||
)
|
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
|
|
||||||
scan_date = datetime.now().strftime('%Y-%m-%d')
|
scan_date = datetime.now().strftime('%Y-%m-%d')
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ from services.stock_algorithms import (
|
|||||||
)
|
)
|
||||||
from db import (
|
from db import (
|
||||||
login_required, get_current_user_id,
|
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')
|
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)",
|
_cur.execute("INSERT INTO ai_call_log (user_id, stock_code, stock_name) VALUES (%s, %s, %s)",
|
||||||
(_uid, stock_code, stock_name))
|
(_uid, stock_code, stock_name))
|
||||||
_conn.commit()
|
_conn.commit()
|
||||||
_put_db(conn)
|
put_db(_conn)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -544,10 +545,8 @@ def batch_technical_signals():
|
|||||||
"""批量检测技术交易信号 — 优先从 stock_signal_scan 读取(与提醒一致),无记录时实时计算"""
|
"""批量检测技术交易信号 — 优先从 stock_signal_scan 读取(与提醒一致),无记录时实时计算"""
|
||||||
try:
|
try:
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import psycopg2
|
|
||||||
from psycopg2.extras import RealDictCursor
|
from psycopg2.extras import RealDictCursor
|
||||||
from services.signal_detector import detect_all_signals
|
from services.signal_detector import detect_all_signals
|
||||||
from config import Config
|
|
||||||
|
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
codes = data.get('codes', [])
|
codes = data.get('codes', [])
|
||||||
@@ -566,10 +565,9 @@ def batch_technical_signals():
|
|||||||
change_map = {}
|
change_map = {}
|
||||||
scan_map = {}
|
scan_map = {}
|
||||||
try:
|
try:
|
||||||
conn = psycopg2.connect(
|
conn = get_db()
|
||||||
host=Config.DB_HOST, port=Config.DB_PORT,
|
if not conn:
|
||||||
dbname=Config.DB_NAME, user=Config.DB_USER, password=Config.DB_PASSWORD,
|
raise Exception('数据库连接失败')
|
||||||
)
|
|
||||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||||
placeholders = ','.join(['%s'] * len(codes))
|
placeholders = ','.join(['%s'] * len(codes))
|
||||||
|
|
||||||
@@ -675,9 +673,6 @@ def batch_technical_signals():
|
|||||||
def get_scan_results():
|
def get_scan_results():
|
||||||
"""查询全量扫描结果"""
|
"""查询全量扫描结果"""
|
||||||
try:
|
try:
|
||||||
import psycopg2
|
|
||||||
from config import Config
|
|
||||||
|
|
||||||
scan_date = request.args.get('date', datetime.now().strftime('%Y-%m-%d'))
|
scan_date = request.args.get('date', datetime.now().strftime('%Y-%m-%d'))
|
||||||
min_triggered = int(request.args.get('min_triggered', 0))
|
min_triggered = int(request.args.get('min_triggered', 0))
|
||||||
signal_type = request.args.get('signal_type', '')
|
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())
|
holding_set = set(c.strip() for c in holding_codes_str.split(',') if c.strip())
|
||||||
recommend_text = (request.args.get('recommend_text') or '').strip()
|
recommend_text = (request.args.get('recommend_text') or '').strip()
|
||||||
|
|
||||||
conn = psycopg2.connect(
|
conn = get_db()
|
||||||
host=Config.DB_HOST, port=Config.DB_PORT,
|
if not conn:
|
||||||
dbname=Config.DB_NAME, user=Config.DB_USER, password=Config.DB_PASSWORD,
|
return jsonify({'success': False, 'error': '数据库连接失败'}), 500
|
||||||
)
|
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
|
|
||||||
# 检查请求日期是否有数据,如果没有则自动回退到最近可用的扫描日期
|
# 检查请求日期是否有数据,如果没有则自动回退到最近可用的扫描日期
|
||||||
@@ -955,9 +949,7 @@ def _compute_recommend(signal_status, indicators, triggered_count, is_holding):
|
|||||||
@bp.route('/signal_alerts', methods=['POST'])
|
@bp.route('/signal_alerts', methods=['POST'])
|
||||||
def signal_alerts():
|
def signal_alerts():
|
||||||
"""基于信号扫描结果生成买入/卖出/观望提醒(与扫描结果共用 _compute_recommend)"""
|
"""基于信号扫描结果生成买入/卖出/观望提醒(与扫描结果共用 _compute_recommend)"""
|
||||||
import psycopg2
|
|
||||||
from psycopg2.extras import RealDictCursor
|
from psycopg2.extras import RealDictCursor
|
||||||
from config import Config
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
data = request.get_json() or {}
|
data = request.get_json() or {}
|
||||||
@@ -968,10 +960,9 @@ def signal_alerts():
|
|||||||
if not stock_codes:
|
if not stock_codes:
|
||||||
return jsonify({'success': True, 'results': []})
|
return jsonify({'success': True, 'results': []})
|
||||||
|
|
||||||
conn = psycopg2.connect(
|
conn = get_db()
|
||||||
host=Config.DB_HOST, port=Config.DB_PORT,
|
if not conn:
|
||||||
dbname=Config.DB_NAME, user=Config.DB_USER, password=Config.DB_PASSWORD,
|
return jsonify({'success': False, 'error': '数据库连接失败'}), 500
|
||||||
)
|
|
||||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||||
|
|
||||||
# 优先今天的扫描数据,无则回退到最近可用日期
|
# 优先今天的扫描数据,无则回退到最近可用日期
|
||||||
@@ -1127,13 +1118,9 @@ def get_stock_score_detail(code):
|
|||||||
def get_scan_status():
|
def get_scan_status():
|
||||||
"""查询扫描进度"""
|
"""查询扫描进度"""
|
||||||
try:
|
try:
|
||||||
import psycopg2
|
conn = get_db()
|
||||||
from config import Config
|
if not conn:
|
||||||
|
return jsonify({'success': False, 'error': '数据库连接失败'}), 500
|
||||||
conn = psycopg2.connect(
|
|
||||||
host=Config.DB_HOST, port=Config.DB_PORT,
|
|
||||||
dbname=Config.DB_NAME, user=Config.DB_USER, password=Config.DB_PASSWORD,
|
|
||||||
)
|
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
|
|
||||||
scan_date = datetime.now().strftime('%Y-%m-%d')
|
scan_date = datetime.now().strftime('%Y-%m-%d')
|
||||||
@@ -1210,18 +1197,15 @@ def start_full_scan():
|
|||||||
def get_scan_strategy():
|
def get_scan_strategy():
|
||||||
"""基于体系最强战法,给出分梯队买卖建议。与全景扫描推荐共用 _compute_recommend,算法一致。"""
|
"""基于体系最强战法,给出分梯队买卖建议。与全景扫描推荐共用 _compute_recommend,算法一致。"""
|
||||||
try:
|
try:
|
||||||
import psycopg2
|
|
||||||
from psycopg2.extras import RealDictCursor
|
from psycopg2.extras import RealDictCursor
|
||||||
from config import Config
|
|
||||||
|
|
||||||
scan_date = request.args.get('date', datetime.now().strftime('%Y-%m-%d'))
|
scan_date = request.args.get('date', datetime.now().strftime('%Y-%m-%d'))
|
||||||
holding_codes_str = request.args.get('holding_codes', '')
|
holding_codes_str = request.args.get('holding_codes', '')
|
||||||
holding_set = set(c.strip() for c in holding_codes_str.split(',') if c.strip())
|
holding_set = set(c.strip() for c in holding_codes_str.split(',') if c.strip())
|
||||||
|
|
||||||
conn = psycopg2.connect(
|
conn = get_db()
|
||||||
host=Config.DB_HOST, port=Config.DB_PORT,
|
if not conn:
|
||||||
dbname=Config.DB_NAME, user=Config.DB_USER, password=Config.DB_PASSWORD,
|
return jsonify({'success': False, 'error': '数据库连接失败'}), 500
|
||||||
)
|
|
||||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||||
|
|
||||||
# 如果前端未指定日期,且当天无数据,自动回退到最近扫描日期
|
# 如果前端未指定日期,且当天无数据,自动回退到最近扫描日期
|
||||||
@@ -1345,19 +1329,16 @@ def get_bull_stocks():
|
|||||||
stage: 可选,筛选特定阶段(1-5)
|
stage: 可选,筛选特定阶段(1-5)
|
||||||
holdingStocks: 可选,持仓代码逗号分隔
|
holdingStocks: 可选,持仓代码逗号分隔
|
||||||
"""
|
"""
|
||||||
import psycopg2
|
|
||||||
from psycopg2.extras import RealDictCursor
|
from psycopg2.extras import RealDictCursor
|
||||||
from config import Config
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
stage_filter = request.args.get('stage', type=int, default=0)
|
stage_filter = request.args.get('stage', type=int, default=0)
|
||||||
holding_str = request.args.get('holdingStocks', '')
|
holding_str = request.args.get('holdingStocks', '')
|
||||||
holding_codes = set(holding_str.split(',')) if holding_str else set()
|
holding_codes = set(holding_str.split(',')) if holding_str else set()
|
||||||
|
|
||||||
conn = psycopg2.connect(
|
conn = get_db()
|
||||||
host=Config.DB_HOST, port=Config.DB_PORT,
|
if not conn:
|
||||||
dbname=Config.DB_NAME, user=Config.DB_USER, password=Config.DB_PASSWORD,
|
return jsonify({'success': False, 'error': '数据库连接失败'}), 500
|
||||||
)
|
|
||||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||||
|
|
||||||
# 获取最近一次扫描数据(过滤退市/ST)
|
# 获取最近一次扫描数据(过滤退市/ST)
|
||||||
|
|||||||
Reference in New Issue
Block a user