Browse Source

修正CalendarInfo模型,完善数据库操作。

maxiaolong 3 days ago
parent
commit
6ed55e5bf7
2 changed files with 214 additions and 58 deletions
  1. 136 58
      app/core/data_parse/calendar.py
  2. 78 0
      test_calendar_basic.py

+ 136 - 58
app/core/data_parse/calendar.py

@@ -6,18 +6,15 @@
 from datetime import date
 from typing import Optional
 from sqlalchemy import Column, Integer, Date, Text, String
-from sqlalchemy.ext.declarative import declarative_base
 from sqlalchemy.orm import Session
 from sqlalchemy import create_engine, text
 import json
 import requests
+from app import db
 from .calendar_config import CALENDAR_API_CONFIG
 
-# 创建基础模型类
-Base = declarative_base()
 
-
-class CalendarInfo(Base):
+class CalendarInfo(db.Model):
     """
     黄历信息表数据模型
     
@@ -28,34 +25,37 @@ class CalendarInfo(Base):
     __table_args__ = {'schema': 'public'}
     
     # 主键ID (serial primary key)
-    id = Column(Integer, primary_key=True, autoincrement=True, comment='主键ID')
+    id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='主键ID')
     
     # 阳历日期 (date not null)
-    yangli = Column(Date, nullable=False, comment='阳历日期')
+    yangli = db.Column(db.Date, nullable=False, comment='阳历日期')
     
     # 阴历日期 (text not null)
-    yinli = Column(Text, nullable=False, comment='阴历日期')
+    yinli = db.Column(db.Text, nullable=False, comment='阴历日期')
     
     # 五行 (text)
-    wuxing = Column(Text, nullable=True, comment='五行')
+    wuxing = db.Column(db.Text, nullable=True, comment='五行')
     
     # 冲煞 (text)
-    chongsha = Column(Text, nullable=True, comment='冲煞')
+    chongsha = db.Column(db.Text, nullable=True, comment='冲煞')
     
     # 彭祖百忌 (text)
-    baiji = Column(Text, nullable=True, comment='彭祖百忌')
+    baiji = db.Column(db.Text, nullable=True, comment='彭祖百忌')
     
     # 吉神宜趋 (text)
-    jishen = Column(Text, nullable=True, comment='吉神宜趋')
+    jishen = db.Column(db.Text, nullable=True, comment='吉神宜趋')
     
     # 宜 (text)
-    yi = Column(Text, nullable=True, comment='宜')
+    yi = db.Column(db.Text, nullable=True, comment='宜')
     
     # 凶神宜忌 (text)
-    xiongshen = Column(Text, nullable=True, comment='凶神宜忌')
+    xiongshen = db.Column(db.Text, nullable=True, comment='凶神宜忌')
     
     # 忌 (text)
-    ji = Column(Text, nullable=True, comment='忌')
+    ji = db.Column(db.Text, nullable=True, comment='忌')
+    
+    def __init__(self, **kwargs):
+        super().__init__(**kwargs)
     
     def __repr__(self):
         return f"<CalendarInfo(id={self.id}, yangli='{self.yangli}', yinli='{self.yinli}')>"
@@ -109,15 +109,15 @@ class CalendarInfo(Base):
                 yangli = None
         
         return cls(
-            yangli=yangli,
-            yinli=data.get('yinli'),
-            wuxing=data.get('wuxing'),
-            chongsha=data.get('chongsha'),
-            baiji=data.get('baiji'),
-            jishen=data.get('jishen'),
-            yi=data.get('yi'),
-            xiongshen=data.get('xiongshen'),
-            ji=data.get('ji')
+            yangli=yangli,  # type: ignore
+            yinli=data.get('yinli'),  # type: ignore
+            wuxing=data.get('wuxing'),  # type: ignore
+            chongsha=data.get('chongsha'),  # type: ignore
+            baiji=data.get('baiji'),  # type: ignore
+            jishen=data.get('jishen'),  # type: ignore
+            yi=data.get('yi'),  # type: ignore
+            xiongshen=data.get('xiongshen'),  # type: ignore
+            ji=data.get('ji')  # type: ignore
         )
 
 
@@ -132,7 +132,7 @@ class CalendarService:
         初始化服务
         
         Args:
-            engine: SQLAlchemy引擎对象,如果为None则使用默认配置
+            engine: SQLAlchemy引擎对象,如果为None则使用Flask-SQLAlchemy的db.session
         """
         self.engine = engine
     
@@ -148,10 +148,16 @@ class CalendarService:
         """
         calendar_info = CalendarInfo.from_dict(calendar_data)
         
-        with Session(self.engine) as session:
-            session.add(calendar_info)
-            session.commit()
-            session.refresh(calendar_info)
+        if self.engine:
+            with Session(self.engine) as session:
+                session.add(calendar_info)
+                session.commit()
+                session.refresh(calendar_info)
+        else:
+            # 使用Flask-SQLAlchemy的db.session
+            db.session.add(calendar_info)
+            db.session.commit()
+            db.session.refresh(calendar_info)
             
         return calendar_info
     
@@ -165,8 +171,14 @@ class CalendarService:
         Returns:
             Optional[CalendarInfo]: 黄历信息对象,如果不存在则返回None
         """
-        with Session(self.engine) as session:
-            return session.query(CalendarInfo).filter(
+        if self.engine:
+            with Session(self.engine) as session:
+                return session.query(CalendarInfo).filter(
+                    CalendarInfo.yangli == yangli_date
+                ).first()
+        else:
+            # 使用Flask-SQLAlchemy的db.session
+            return CalendarInfo.query.filter(
                 CalendarInfo.yangli == yangli_date
             ).first()
     
@@ -180,8 +192,14 @@ class CalendarService:
         Returns:
             Optional[CalendarInfo]: 黄历信息对象,如果不存在则返回None
         """
-        with Session(self.engine) as session:
-            return session.query(CalendarInfo).filter(
+        if self.engine:
+            with Session(self.engine) as session:
+                return session.query(CalendarInfo).filter(
+                    CalendarInfo.id == calendar_id
+                ).first()
+        else:
+            # 使用Flask-SQLAlchemy的db.session
+            return CalendarInfo.query.filter(
                 CalendarInfo.id == calendar_id
             ).first()
     
@@ -196,8 +214,31 @@ class CalendarService:
         Returns:
             Optional[CalendarInfo]: 更新后的黄历信息对象,如果不存在则返回None
         """
-        with Session(self.engine) as session:
-            calendar_info = session.query(CalendarInfo).filter(
+        if self.engine:
+            with Session(self.engine) as session:
+                calendar_info = session.query(CalendarInfo).filter(
+                    CalendarInfo.id == calendar_id
+                ).first()
+                
+                if not calendar_info:
+                    return None
+                
+                # 更新字段
+                for key, value in update_data.items():
+                    if hasattr(calendar_info, key):
+                        if key == 'yangli' and isinstance(value, str):
+                            try:
+                                value = date.fromisoformat(value)
+                            except ValueError:
+                                continue
+                        setattr(calendar_info, key, value)
+                
+                session.commit()
+                session.refresh(calendar_info)
+                
+        else:
+            # 使用Flask-SQLAlchemy的db.session
+            calendar_info = CalendarInfo.query.filter(
                 CalendarInfo.id == calendar_id
             ).first()
             
@@ -214,8 +255,8 @@ class CalendarService:
                             continue
                     setattr(calendar_info, key, value)
             
-            session.commit()
-            session.refresh(calendar_info)
+            db.session.commit()
+            db.session.refresh(calendar_info)
             
         return calendar_info
     
@@ -229,16 +270,28 @@ class CalendarService:
         Returns:
             bool: 删除成功返回True,否则返回False
         """
-        with Session(self.engine) as session:
-            calendar_info = session.query(CalendarInfo).filter(
+        if self.engine:
+            with Session(self.engine) as session:
+                calendar_info = session.query(CalendarInfo).filter(
+                    CalendarInfo.id == calendar_id
+                ).first()
+                
+                if not calendar_info:
+                    return False
+                
+                session.delete(calendar_info)
+                session.commit()
+        else:
+            # 使用Flask-SQLAlchemy的db.session
+            calendar_info = CalendarInfo.query.filter(
                 CalendarInfo.id == calendar_id
             ).first()
             
             if not calendar_info:
                 return False
             
-            session.delete(calendar_info)
-            session.commit()
+            db.session.delete(calendar_info)
+            db.session.commit()
             
         return True
     
@@ -253,8 +306,14 @@ class CalendarService:
         Returns:
             list[CalendarInfo]: 黄历信息对象列表
         """
-        with Session(self.engine) as session:
-            return session.query(CalendarInfo).order_by(
+        if self.engine:
+            with Session(self.engine) as session:
+                return session.query(CalendarInfo).order_by(
+                    CalendarInfo.yangli.desc()
+                ).offset(offset).limit(limit).all()
+        else:
+            # 使用Flask-SQLAlchemy的db.session
+            return CalendarInfo.query.order_by(
                 CalendarInfo.yangli.desc()
             ).offset(offset).limit(limit).all()
     
@@ -269,8 +328,21 @@ class CalendarService:
         Returns:
             list[CalendarInfo]: 匹配的黄历信息对象列表
         """
-        with Session(self.engine) as session:
-            return session.query(CalendarInfo).filter(
+        if self.engine:
+            with Session(self.engine) as session:
+                return session.query(CalendarInfo).filter(
+                    (CalendarInfo.yinli.contains(keyword)) |
+                    (CalendarInfo.wuxing.contains(keyword)) |
+                    (CalendarInfo.chongsha.contains(keyword)) |
+                    (CalendarInfo.baiji.contains(keyword)) |
+                    (CalendarInfo.jishen.contains(keyword)) |
+                    (CalendarInfo.yi.contains(keyword)) |
+                    (CalendarInfo.xiongshen.contains(keyword)) |
+                    (CalendarInfo.ji.contains(keyword))
+                ).limit(limit).all()
+        else:
+            # 使用Flask-SQLAlchemy的db.session
+            return CalendarInfo.query.filter(
                 (CalendarInfo.yinli.contains(keyword)) |
                 (CalendarInfo.wuxing.contains(keyword)) |
                 (CalendarInfo.chongsha.contains(keyword)) |
@@ -355,22 +427,28 @@ class CalendarService:
             
             # 创建CalendarInfo对象
             calendar_info = CalendarInfo(
-                yangli=yangli_date,
-                yinli=api_data.get('yinli', ''),
-                wuxing=api_data.get('wuxing'),
-                chongsha=api_data.get('chongsha'),
-                baiji=api_data.get('baiji'),
-                jishen=api_data.get('jishen'),
-                yi=api_data.get('yi'),
-                xiongshen=api_data.get('xionshen'),  # 注意API返回的是xionshen
-                ji=api_data.get('ji')
+                yangli=yangli_date,  # type: ignore
+                yinli=api_data.get('yinli', ''),  # type: ignore
+                wuxing=api_data.get('wuxing'),  # type: ignore
+                chongsha=api_data.get('chongsha'),  # type: ignore
+                baiji=api_data.get('baiji'),  # type: ignore
+                jishen=api_data.get('jishen'),  # type: ignore
+                yi=api_data.get('yi'),  # type: ignore
+                xiongshen=api_data.get('xionshen'),  # type: ignore  # 注意API返回的是xionshen
+                ji=api_data.get('ji')  # type: ignore
             )
             
             # 保存到数据库
-            with Session(self.engine) as session:
-                session.add(calendar_info)
-                session.commit()
-                session.refresh(calendar_info)
+            if self.engine:
+                with Session(self.engine) as session:
+                    session.add(calendar_info)
+                    session.commit()
+                    session.refresh(calendar_info)
+            else:
+                # 使用Flask-SQLAlchemy的db.session
+                db.session.add(calendar_info)
+                db.session.commit()
+                db.session.refresh(calendar_info)
                 
             print(f"成功保存黄历信息到数据库,ID: {calendar_info.id}")
             return calendar_info

+ 78 - 0
test_calendar_basic.py

@@ -0,0 +1,78 @@
+"""
+简单测试CalendarInfo模型的基本功能
+"""
+
+import sys
+import os
+sys.path.append(os.path.dirname(os.path.abspath(__file__)))
+
+def test_calendar_info_model():
+    """测试CalendarInfo模型的基本功能"""
+    print("=== 测试CalendarInfo模型基本功能 ===")
+    
+    try:
+        # 导入模型
+        from app.core.data_parse.calendar import CalendarInfo
+        
+        print("✅ 成功导入CalendarInfo模型")
+        
+        # 测试模型属性
+        print(f"表名: {CalendarInfo.__tablename__}")
+        print(f"表参数: {CalendarInfo.__table_args__}")
+        
+        # 测试字段定义
+        print("字段定义:")
+        for column in CalendarInfo.__table__.columns:  # type: ignore
+            print(f"  - {column.name}: {column.type}")
+        
+        print("✅ CalendarInfo模型定义正确")
+        
+    except Exception as e:
+        print(f"❌ 测试失败: {e}")
+        import traceback
+        traceback.print_exc()
+
+def test_calendar_info_creation():
+    """测试CalendarInfo对象的创建"""
+    print("\n=== 测试CalendarInfo对象创建 ===")
+    
+    try:
+        from app.core.data_parse.calendar import CalendarInfo
+        from datetime import date
+        
+        # 创建测试数据
+        test_data = {
+            'yangli': '2025-01-19',
+            'yinli': '甲午(马)年八月十八',
+            'wuxing': '井泉水 建执位',
+            'chongsha': '冲兔(己卯)煞东',
+            'baiji': '乙不栽植千株不长 酉不宴客醉坐颠狂',
+            'jishen': '官日 六仪 益後 月德合 除神 玉堂 鸣犬',
+            'yi': '祭祀 出行 扫舍 馀事勿取',
+            'xiongshen': '月建 小时 土府 月刑 厌对 招摇 五离',
+            'ji': '诸事不宜'
+        }
+        
+        # 使用from_dict方法创建对象
+        calendar_info = CalendarInfo.from_dict(test_data)
+        print("✅ 成功创建CalendarInfo对象")
+        
+        # 测试to_dict方法
+        result_dict = calendar_info.to_dict()
+        print("✅ to_dict方法工作正常")
+        print(f"转换结果: {result_dict}")
+        
+        # 测试to_json方法
+        json_str = calendar_info.to_json()
+        print("✅ to_json方法工作正常")
+        print(f"JSON字符串: {json_str}")
+        
+    except Exception as e:
+        print(f"❌ 测试失败: {e}")
+        import traceback
+        traceback.print_exc()
+
+if __name__ == "__main__":
+    test_calendar_info_model()
+    test_calendar_info_creation()
+    print("\n🎉 基本功能测试完成!")