superxuu commited on
Commit
b36f33b
·
1 Parent(s): a26b941

fix: Switch to download-based Parquet loading to resolve DuckDB httpfs issues in HF Space

Browse files
Files changed (1) hide show
  1. backend/app/database.py +14 -14
backend/app/database.py CHANGED
@@ -76,32 +76,32 @@ class DatabaseManager:
76
  is_hf = os.getenv("SPACES_REPO_NAME") is not None or (HF_TOKEN and DATASET_REPO_ID)
77
 
78
  if is_hf:
79
- logger.info("HF environment detected. Mounting remote Parquet files...")
80
  try:
81
  from huggingface_hub import list_repo_files, hf_hub_download
82
 
83
- # 1. 配置 DuckDB HTTP 访问
84
- conn.execute("INSTALL httpfs; LOAD httpfs;")
85
- if HF_TOKEN:
86
- header_json = f'{{"Authorization": "Bearer {HF_TOKEN}"}}'
87
- conn.execute(f"SET http_headers='{header_json}';")
88
-
89
- # 2. 动态获取文件列表
90
  all_files = list_repo_files(repo_id=DATASET_REPO_ID, repo_type="dataset")
91
 
92
- # 3. 股票列表:直接下载到本地 (因为很小且查询频繁)
93
  list_file = "data/stock_list.parquet"
94
  if list_file in all_files:
95
  local_list_path = hf_hub_download(repo_id=DATASET_REPO_ID, filename=list_file, repo_type="dataset")
96
  conn.execute(f"CREATE OR REPLACE TABLE stock_list AS SELECT * FROM read_parquet('{local_list_path}')")
97
  logger.info("Local stock_list table created from remote parquet")
98
 
99
- # 4. 挂载日线数据 (保持远程挂载)
100
- parquet_files = [f"https://huggingface.co/datasets/{DATASET_REPO_ID}/resolve/main/{f}"
101
- for f in all_files if f.startswith("data/parquet/") and f.endswith(".parquet")]
102
 
103
  if parquet_files:
104
- files_sql = ", ".join([f"'{f}'" for f in parquet_files])
 
 
 
 
 
 
105
  conn.execute(f"CREATE OR REPLACE VIEW stock_daily AS SELECT * FROM read_parquet([{files_sql}])")
106
  logger.info(f"Remote stock_daily view created with {len(parquet_files)} partitions")
107
  else:
@@ -113,7 +113,7 @@ class DatabaseManager:
113
  logger.info(f"Verification successful: {count} stocks found")
114
 
115
  except Exception as e:
116
- logger.error(f"Failed to mount remote Parquet: {e}")
117
  self._create_tables()
118
  else:
119
  self._create_tables()
 
76
  is_hf = os.getenv("SPACES_REPO_NAME") is not None or (HF_TOKEN and DATASET_REPO_ID)
77
 
78
  if is_hf:
79
+ logger.info("HF environment detected. Downloading remote Parquet files...")
80
  try:
81
  from huggingface_hub import list_repo_files, hf_hub_download
82
 
83
+ # 1. 动态获取文件列表
 
 
 
 
 
 
84
  all_files = list_repo_files(repo_id=DATASET_REPO_ID, repo_type="dataset")
85
 
86
+ # 2. 股票列表:下载并加载
87
  list_file = "data/stock_list.parquet"
88
  if list_file in all_files:
89
  local_list_path = hf_hub_download(repo_id=DATASET_REPO_ID, filename=list_file, repo_type="dataset")
90
  conn.execute(f"CREATE OR REPLACE TABLE stock_list AS SELECT * FROM read_parquet('{local_list_path}')")
91
  logger.info("Local stock_list table created from remote parquet")
92
 
93
+ # 3. 日线数据:下载并加载 (下载模式替代挂载模式)
94
+ # 注意:如果文件很多,这步可能会花点时间,但比下载整个 .duckdb 快得多
95
+ parquet_files = [f for f in all_files if f.startswith("data/parquet/") and f.endswith(".parquet")]
96
 
97
  if parquet_files:
98
+ local_paths = []
99
+ for f in parquet_files:
100
+ # HF SDK 会自动处理缓存,已下载的文件不会重复下载
101
+ path = hf_hub_download(repo_id=DATASET_REPO_ID, filename=f, repo_type="dataset")
102
+ local_paths.append(f"'{path}'")
103
+
104
+ files_sql = ", ".join(local_paths)
105
  conn.execute(f"CREATE OR REPLACE VIEW stock_daily AS SELECT * FROM read_parquet([{files_sql}])")
106
  logger.info(f"Remote stock_daily view created with {len(parquet_files)} partitions")
107
  else:
 
113
  logger.info(f"Verification successful: {count} stocks found")
114
 
115
  except Exception as e:
116
+ logger.error(f"Failed to load remote Parquet: {e}")
117
  self._create_tables()
118
  else:
119
  self._create_tables()