使用SQLAlchemy 2.0批量操作MSSQL时datetime2字段值丢失
解决SQLAlchemy 2.0操作MSSQL时datetime2字段写入NULL的问题
问题场景
使用SQLAlchemy 2.0对MSSQL数据库执行批量插入和更新操作时,其他字段能正常写入,但两个datetime2类型字段始终被忽略,最终存入NULL值。尝试过传入日期对象和字符串两种形式都无效,但手动向MSSQL插入数据可正常接收。
相关代码
模型定义代码
import datetime from sqlalchemy import DateTime, ForeignKey, String, insert, update from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship from sqlalchemy.dialects.mssql import DATETIME2 from dateutil import parser class Base(DeclarativeBase): pass class issues(Base): __tablename__ = "issues" id = mapped_column(String(36), primary_key=True) created = mapped_column (DATETIME2()) updated = mapped_column (DATETIME2()) status = mapped_column(String(50)) severity = mapped_column(String(10)) control_id = mapped_column(String(36)) entity_id = mapped_column(String(36))
数据构造及操作代码
issueList.append({ 'id': issue['id'], # 'createdAt': parser.parse(issue['createdAt']).__str__(), 'createdAt': parser.parse(issue['createdAt']), # 'updatedAt': parser.parse(issue['updatedAt']).__str__(), 'updatedAt': parser.parse(issue['updatedAt']), 'status': issue['status'], 'severity': issue['severity'], 'control_id': issue['control']['id'], 'entity_id': issue['entity']['id'] }) session.execute(insert(issues),issueList) session.execute(update(issues),issueListUpdates) session.commit()
解决方案
核心问题是字段名不匹配:模型类issues中定义的datetime2字段是created和updated,但数据构造时使用的键名是createdAt和updatedAt,SQLAlchemy无法将这两个键映射到模型对应的字段,因此直接忽略,导致存入NULL。
1. 修正数据构造的键名
将数据字典中的键名修改为与模型字段完全一致:
issueList.append({ 'id': issue['id'], 'created': parser.parse(issue['createdAt']), # 匹配模型的created字段 'updated': parser.parse(issue['updatedAt']), # 匹配模型的updated字段 'status': issue['status'], 'severity': issue['severity'], 'control_id': issue['control']['id'], 'entity_id': issue['entity']['id'] })
2. 额外验证要点
- 确保
parser.parse()返回的是有效的datetime.datetime对象,SQLAlchemy会自动处理其与MSSQL DATETIME2类型的转换,无需手动转为字符串。 - 检查更新操作使用的
issueListUpdates字典,确保其中的datetime字段键名同样与模型字段一致,避免重复出现问题。
内容的提问来源于stack exchange,提问作者trevrobwhite
相关产品推荐
相关产品推荐

