| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- """
- 期货数据管理系统的Flask应用包
- """
- import os
- import yaml
- import click
- from flask import Flask
- from app.database.db_manager import db, migrate, init_db
- from app.routes.future_info import bp as future_info_bp
- from app.routes.transaction import bp as transaction_bp
- from app.routes.trade import bp as trade_bp
- from app.routes.monitor import bp as monitor_bp
- from app.routes.dimension import bp as dimension_bp
- def _update_flask_config_from_service(app):
- """
- 从配置服务更新Flask应用配置
- 在数据库初始化完成后调用,尝试从配置数据库更新Flask配置
- """
- try:
- with app.app_context():
- from app.services.config_service import get_str_config, get_bool_config
-
- # 更新支持热更新的配置
- secret_key = get_str_config('flask_secret_key', app.config.get('SECRET_KEY', 'dev'))
- if secret_key and secret_key != 'dev': # 只有在非默认值时才更新
- app.config['SECRET_KEY'] = secret_key
- print(f"Flask SECRET_KEY 已从配置服务更新")
-
- # 更新SQLAlchemy配置
- track_modifications = get_bool_config('sqlalchemy_track_modifications', False)
- app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = track_modifications
-
- # 数据库URI通常不支持热更新,但我们可以记录当前配置
- db_prefix = get_str_config('database_uri_prefix', 'sqlite:///')
- print(f"数据库配置已确认: 前缀={db_prefix}, 追踪修改={track_modifications}")
-
- except Exception as e:
- print(f"从配置服务更新Flask配置失败,继续使用默认配置: {e}")
- def _initialize_config_service(app):
- """
- 初始化配置服务缓存
- 在数据库完全准备好后调用,预热配置缓存
- """
- try:
- with app.app_context():
- from app.services.config_service import config_service
-
- # 强制刷新配置缓存,预热缓存
- config_service._refresh_cache()
- print("配置服务缓存初始化完成")
-
- except Exception as e:
- print(f"配置服务缓存初始化失败: {e}")
- def create_app(test_config=None):
- """创建并配置Flask应用"""
- app = Flask(__name__, instance_relative_config=True)
-
- # 设置默认配置(先使用硬编码默认值)
- app.config.from_mapping(
- SECRET_KEY='dev',
- SQLALCHEMY_DATABASE_URI=f'sqlite:///{os.path.join(os.path.dirname(os.path.dirname(__file__)), "data", "financial_tools.db")}',
- SQLALCHEMY_TRACK_MODIFICATIONS=False,
- )
- # 加载配置文件
- if test_config is None:
- # 尝试从config.yaml加载配置
- config_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'config.yaml')
- if os.path.exists(config_path):
- with open(config_path, 'r', encoding='utf-8') as f:
- config = yaml.safe_load(f)
- if config and 'flask' in config:
- app.config.update(config['flask'])
- else:
- # 使用测试配置
- app.config.from_mapping(test_config)
- # 确保data文件夹存在
- data_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'data')
- try:
- os.makedirs(data_path, exist_ok=True)
- except OSError:
- pass
-
- # 确保实例文件夹存在
- try:
- os.makedirs(app.instance_path)
- except OSError:
- pass
- # 初始化数据库
- init_db(app)
-
- # 数据库初始化完成后,尝试从配置服务更新Flask配置
- _update_flask_config_from_service(app)
-
- # 初始化配置服务缓存
- _initialize_config_service(app)
- # 注册蓝图
- register_blueprints(app)
- # 初始化数据更新服务
- from app.services.data_update import init_data_update_service
- init_data_update_service(app)
-
- # 注册命令行命令
- register_commands(app)
- # 注册首页路由
- @app.route('/')
- def index():
- from flask import render_template
- return render_template('index.html')
- return app
- def register_blueprints(app):
- app.register_blueprint(future_info_bp)
- app.register_blueprint(transaction_bp)
- app.register_blueprint(trade_bp)
- app.register_blueprint(monitor_bp)
- app.register_blueprint(dimension_bp)
- def register_commands(app):
- """注册Flask命令行命令"""
- @app.cli.command('update-future-data')
- @click.option('--mode', '-m', type=click.Choice(['daily', 'info', 'both']), default='both',
- help='更新模式: daily=只更新future_daily表, info=只更新future_info表, both=两者都更新')
- def update_future_data(mode):
- """更新期货数据,包括future_daily和future_info表"""
- from app.models.future_info import FutureInfo, FutureDaily
- from app.services.data_scraper import FutureDataScraper
-
- click.echo(f"开始更新期货数据,模式: {mode}")
-
- scraper = FutureDataScraper()
-
- if mode in ['daily', 'both']:
- # 更新future_daily表
- click.echo("正在更新future_daily表...")
- records_count = scraper.update_future_daily(db.session, FutureDaily)
- click.echo(f"future_daily表更新完成,共{records_count}条记录")
-
- if mode in ['info', 'both']:
- if mode == 'both':
- # 根据future_daily表更新future_info表
- click.echo("正在根据future_daily表更新future_info表...")
- updated_count = scraper.update_future_info_from_daily(db.session, FutureInfo, FutureDaily)
- else:
- # 直接从网站更新future_info表
- click.echo("正在直接从网站更新future_info表...")
- updated_count = scraper.update_future_info(db.session, FutureInfo)
- click.echo(f"future_info表更新完成,共更新{updated_count}条记录")
-
- click.echo("期货数据更新任务完成")
-
- @app.cli.command('init-trend-info')
- @click.option('--force', '-f', is_flag=True, help='强制重新初始化,清空现有数据')
- def init_trend_info_cmd(force):
- """初始化trend_info表数据,从config/trend_list.csv导入"""
- from app.models.dimension import TrendInfo
- from app.database.init_trend_info import init_trend_info
-
- if force:
- # 如果强制初始化,先清空现有数据
- click.echo("正在清空trend_info表...")
- db.session.query(TrendInfo).delete()
- db.session.commit()
- click.echo("trend_info表已清空")
-
- # 初始化trend_info表
- click.echo("正在初始化trend_info表...")
- init_trend_info()
- count = db.session.query(TrendInfo).count()
- click.echo(f"trend_info表初始化完成,共{count}条记录")
- @app.cli.command('init-candle-info')
- @click.option('--force', '-f', is_flag=True, help='强制重新初始化,清空现有数据')
- def init_candle_info_cmd(force):
- """初始化candle_info表数据,从config/candle_info.csv导入"""
- from app.models.dimension import CandleInfo
- from app.database.init_trend_info import init_candle_info
-
- if force:
- # 如果强制初始化,先清空现有数据
- click.echo("正在清空candle_info表...")
- db.session.query(CandleInfo).delete()
- db.session.commit()
- click.echo("candle_info表已清空")
-
- # 初始化candle_info表
- click.echo("正在初始化candle_info表...")
- init_candle_info()
- count = db.session.query(CandleInfo).count()
- click.echo(f"candle_info表初始化完成,共{count}条记录")
|