Files
ewoooc/database/import_models.py
ogt e611702bb9 refactor: unify 4 isolated SQLAlchemy Base instances to database.models.Base
- database/import_models.py: 移除 ext.declarative.declarative_base,改用 from database.models import Base
- database/notification_models.py: 同上
- database/ppt_reports.py: 移除 orm.declarative_base,改用共用 Base
- database/vendor_models.py: 同上
- database/manager.py: 加入 4 個模型的 noqa import,確保 Base.metadata 完整管理所有資料表

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 21:27:20 +08:00

113 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
匯入進度追蹤模型
"""
from sqlalchemy import Column, Integer, String, DateTime, Text, Float
from database.models import Base
from datetime import datetime
import pytz
# 台北時區
TAIPEI_TZ = pytz.timezone('Asia/Taipei')
def taipei_now():
"""取得台北時區的當前時間(無時區資訊,用於資料庫存儲)"""
return datetime.now(TAIPEI_TZ).replace(tzinfo=None)
class ImportJob(Base):
"""匯入任務模型"""
__tablename__ = 'import_jobs'
id = Column(Integer, primary_key=True, autoincrement=True, comment='匯入任務 ID')
# 任務資訊
job_type = Column(String(50), nullable=False, comment='任務類型daily_sales, vendor_stockout')
status = Column(String(20), nullable=False, default='pending', comment='狀態pending, downloading, importing, completed, failed')
# Google Drive 檔案資訊
drive_file_id = Column(String(200), comment='Google Drive 檔案 ID')
drive_file_name = Column(String(500), comment='Google Drive 檔案名稱')
drive_file_size = Column(Integer, comment='檔案大小bytes')
# 本地檔案資訊
local_file_path = Column(String(500), comment='本地檔案路徑')
# 進度資訊
progress_percent = Column(Float, default=0.0, comment='進度百分比 (0-100)')
current_step = Column(String(200), comment='當前步驟描述')
total_rows = Column(Integer, comment='總行數')
processed_rows = Column(Integer, default=0, comment='已處理行數')
success_rows = Column(Integer, default=0, comment='成功匯入行數')
error_rows = Column(Integer, default=0, comment='錯誤行數')
# 時間記錄 (2026-01-30 修正:使用台北時區)
created_at = Column(DateTime, default=taipei_now, comment='建立時間')
started_at = Column(DateTime, comment='開始時間')
completed_at = Column(DateTime, comment='完成時間')
# 結果資訊
error_message = Column(Text, comment='錯誤訊息')
import_summary = Column(Text, comment='匯入摘要JSON 格式)')
def __repr__(self):
return f"<ImportJob(id={self.id}, type={self.job_type}, status={self.status}, progress={self.progress_percent}%)>"
def to_dict(self):
"""轉換為字典格式"""
return {
'id': self.id,
'job_type': self.job_type,
'status': self.status,
'drive_file_id': self.drive_file_id,
'drive_file_name': self.drive_file_name,
'drive_file_size': self.drive_file_size,
'local_file_path': self.local_file_path,
'progress_percent': self.progress_percent,
'current_step': self.current_step,
'total_rows': self.total_rows,
'processed_rows': self.processed_rows,
'success_rows': self.success_rows,
'error_rows': self.error_rows,
'created_at': self.created_at.isoformat() if self.created_at else None,
'started_at': self.started_at.isoformat() if self.started_at else None,
'completed_at': self.completed_at.isoformat() if self.completed_at else None,
'error_message': self.error_message,
'import_summary': self.import_summary,
}
class ImportConfig(Base):
"""匯入配置模型"""
__tablename__ = 'import_config'
id = Column(Integer, primary_key=True, autoincrement=True)
# 配置項目
config_key = Column(String(100), unique=True, nullable=False, comment='配置鍵')
config_value = Column(Text, comment='配置值')
config_type = Column(String(50), comment='配置類型string, int, bool, json')
description = Column(String(500), comment='配置說明')
# 時間記錄 (2026-01-30 修正:使用台北時區)
created_at = Column(DateTime, default=taipei_now, comment='建立時間')
updated_at = Column(DateTime, default=taipei_now, onupdate=taipei_now, comment='更新時間')
def __repr__(self):
return f"<ImportConfig(key={self.config_key}, value={self.config_value})>"
def to_dict(self):
"""轉換為字典格式"""
return {
'id': self.id,
'config_key': self.config_key,
'config_value': self.config_value,
'config_type': self.config_type,
'description': self.description,
'created_at': self.created_at.isoformat() if self.created_at else None,
'updated_at': self.updated_at.isoformat() if self.updated_at else None,
}