api_call_log.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. """
  2. API调用日志ORM定义
  3. 定义API调用日志的数据库表结构,用于记录每次API调用的详细信息
  4. 支持计费审计和调用统计功能
  5. """
  6. from sqlalchemy import Column, BigInteger, Integer, String, Boolean, DateTime, Text, Numeric, Index, ForeignKey
  7. from sqlalchemy.sql import func
  8. from app.database import Base
  9. class ApiCallLog(Base):
  10. """
  11. API调用日志ORM类
  12. 记录每次API调用的详细信息,包括:
  13. - 调用用户和使用的API Key
  14. - 调用的模型信息(支持云端和本地模型)
  15. - Token用量和费用
  16. - 调用状态和错误信息
  17. """
  18. __tablename__ = "api_call_log"
  19. # 主键ID(使用BigInteger支持大量日志)
  20. id = Column(
  21. BigInteger,
  22. primary_key=True,
  23. autoincrement=True,
  24. comment="主键ID"
  25. )
  26. # 用户ID(外键关联users表)
  27. user_id = Column(
  28. String(50),
  29. ForeignKey("aigcspace.users.id", ondelete="CASCADE"),
  30. nullable=False,
  31. comment="用户ID"
  32. )
  33. # API Key ID(外键关联platform_api_key表,删除时置空)
  34. api_key_id = Column(
  35. Integer,
  36. ForeignKey("aigcspace.platform_api_key.id", ondelete="SET NULL"),
  37. nullable=True,
  38. comment="API Key ID"
  39. )
  40. # 模型ID(不再强制外键约束,中转站场景下模型可能不在本地表中)
  41. model_id = Column(
  42. Integer,
  43. nullable=True,
  44. comment="模型ID"
  45. )
  46. # 模型名称(冗余存储,即使模型被删除也能查看历史记录)
  47. model_name = Column(
  48. String(255),
  49. nullable=False,
  50. comment="模型名称"
  51. )
  52. # 是否为本地模型
  53. is_local = Column(
  54. Boolean,
  55. nullable=False,
  56. default=False,
  57. comment="是否为本地模型"
  58. )
  59. # 输入Token数量
  60. input_tokens = Column(
  61. Integer,
  62. nullable=False,
  63. default=0,
  64. comment="输入Token数量"
  65. )
  66. # 输出Token数量
  67. output_tokens = Column(
  68. Integer,
  69. nullable=False,
  70. default=0,
  71. comment="输出Token数量"
  72. )
  73. # 费用金额(精度12位,小数4位)
  74. bill = Column(
  75. Numeric(12, 4),
  76. nullable=False,
  77. default=0,
  78. comment="费用金额"
  79. )
  80. # 调用状态:success/failed
  81. status = Column(
  82. String(20),
  83. nullable=False,
  84. default="success",
  85. comment="调用状态:success/failed"
  86. )
  87. # 错误信息(调用失败时记录)
  88. error_message = Column(
  89. Text,
  90. nullable=True,
  91. comment="错误信息"
  92. )
  93. # 请求IP地址
  94. request_ip = Column(
  95. String(50),
  96. nullable=True,
  97. comment="请求IP地址"
  98. )
  99. # 创建时间(自动设置)
  100. created_at = Column(
  101. DateTime,
  102. nullable=False,
  103. server_default=func.now(),
  104. comment="创建时间"
  105. )
  106. # 表级配置
  107. __table_args__ = (
  108. Index('idx_api_call_log_user_id', 'user_id'),
  109. Index('idx_api_call_log_api_key_id', 'api_key_id'),
  110. Index('idx_api_call_log_model_id', 'model_id'),
  111. Index('idx_api_call_log_created_at', 'created_at'),
  112. Index('idx_api_call_log_is_local', 'is_local'),
  113. {'schema': 'aigcspace', 'comment': 'API调用日志表'}
  114. )
  115. def __repr__(self):
  116. return f"<ApiCallLog(id={self.id}, user_id='{self.user_id}', model='{self.model_name}', status='{self.status}')>"