SQLAlchemy映射已存在User表报错无法组装主键列如何解决
问题原因
你定义的User ORM类仅声明了关联的表名d_users,没有配置任何字段映射,SQLAlchemy无法识别这张已有表的主键结构,因此抛出了主键组装失败的错误。
此外还有一处隐藏的类型不匹配问题:你的MySQL中d_users表的主键id是varchar(36)类型,但Project类中关联的外键userId定义为了Integer类型,后续运行也会触发外键类型不匹配的错误。
解决方案
修改models.py文件中的两个位置即可:
- 补全
User类的主键字段定义(如果需要用到User表的其他字段,可按需补充映射) - 修正
Project类中userId外键的字段类型,和d_users表的主键类型对齐
修改后的models.py参考代码
from sqlalchemy import Column, ForeignKey, Integer, String, Date, MetaData, Table from sqlalchemy.orm import relationship from .database import Base from datetime import datetime class User(Base): __tablename__ = "d_users" # 必须声明主键字段,类型和数据库实际结构保持一致 id = Column(String(36), primary_key=True, index=True) # 其他字段如果后续需要操作,按需补充即可,不需要的话可以省略 oAuthId = Column(String(48), unique=True, index=True) oAuthType = Column(String(20)) firstName = Column(String(50)) secondName = Column(String(50)) city = Column(String(50)) phone = Column(String(20)) email = Column(String(100), unique=True, index=True) profileLink = Column(String(300)) profilePic = Column(String(300)) status = Column(String(10)) notificationToken = Column(String) password = Column(String(64)) confirmed = Column(Integer) notes = Column(String) created_timestamp = Column(String) updated_timestamp = Column(String) class DataInfo(Base): __tablename__ = "d_data_info" id = Column(Integer, primary_key=True, index=True) isURL = Column(Integer, index=True) dataSource = Column(String(100), index=True) dateCreated = Column(Date, index=True, default=datetime.date(datetime.now())) projectId = Column(Integer, ForeignKey("d_ml_projects.projectId")) data_for_project = relationship("Project", back_populates="data") class Project(Base): __tablename__ = "d_ml_projects" projectId = Column(Integer, primary_key=True, index=True) projectTitle = Column(String(200), index=True) projectDescription = Column(String(550), index=True) problemType = Column(String(15), index=True) classLabel = Column(String(100), index=True) # 修正外键类型为String(36) 和d_users.id的类型对齐 userId = Column(String(36), ForeignKey("d_users.id")) data = relationship("DataInfo", back_populates="data_for_project")
注意事项
Base.metadata.create_all()只会创建不存在的表,已经存在的d_users表不会被修改,不用担心原有数据被覆盖。
内容的提问来源于stack exchange,提问作者anthino12
相关产品推荐
相关产品推荐

