使用SQLAlchemy将SHA1哈希作为SQLite主键插入失败求助
解决FastAPI+SQLite插入SHA1哈希作为主键的类型不匹配问题
问题背景
使用Python FastAPI开发时,尝试将文件内容的SHA1哈希值作为主键插入SQLite数据库,遇到以下问题:
- 初始将主键类型设为
Integer时,提示数值过大 - 改为
String类型后,触发sqlite3.IntegrityError: datatype mismatch错误,但硬编码如"1"的字符串主键可正常插入
相关代码
from sqlalchemy import Column, String, BLOB from sqlalchemy.ext.declarative import declarative_base from fastapi import FastAPI, File, UploadFile, Depends from sqlalchemy.orm import Session import hashlib from typing import List Base = declarative_base() class Object(Base): __tablename__ = "objects" oid = Column(String, primary_key=True) name = Column(String) blob = Column(BLOB) @app.post("/upload") def upload(files: List[UploadFile] = File(..., description= "Upload your files"), db: Session = Depends(database.get_db)): try: for file in files: contents = file.file.read() obj_oid = hashlib.sha1(contents).hexdigest() new_object = models.Object(name=file.filename, blob=contents, oid= str(obj_oid) ) db.add(new_object) db.commit() except Exception as e: db.rollback return {"message": f"There was an error uploading the file(s): {e}"} finally: db.close() return {"message": f"Successfuly uploaded {[file.filename for file in files]}"}
具体错误信息
sqlite3.IntegrityError) datatype mismatch
[SQL: INSERT INTO objects (oid, name, blob) VALUES (?, ?, ?)]
[parameters: ('647968efebd7339771cb51fb960c501074deceb9', 'code.txt', <memory at 0x0000015D9FD9F280>)]
解决方法
- 同步表结构:如果之前用Integer主键创建过表,修改模型后必须重建表或执行迁移。直接删除旧的SQLite数据库文件,让SQLAlchemy根据新模型重新创建表即可——SQLite的动态类型特性不会自动更新已有表的字段类型,这是最常见的问题根源。
- 明确指定String字段长度:SHA1十六进制哈希固定为40个字符,给
oid字段指定长度,避免潜在的类型匹配问题:oid = Column(String(40), primary_key=True) - 简化哈希值赋值:
hashlib.sha1(...).hexdigest()本身返回字符串,无需额外调用str()转换,直接赋值即可:new_object = models.Object(name=file.filename, blob=contents, oid=obj_oid) - 修复回滚代码:原代码中
db.rollback缺少括号,不会执行回滚操作,修正为:db.rollback()
内容的提问来源于stack exchange,提问作者Doruk
相关产品推荐
相关产品推荐

