使用Sequelize从MySQL向GraphQL取数失败,疑惑id等字段来源
嘿,这个问题我太熟悉了!让我给你理清楚这些自动冒出来的字段到底是怎么回事,以及怎么解决~
这些id、createdAt、updatedAt字段从哪来?
都是Sequelize的默认配置在搞事情:
id字段:Sequelize默认会给每个模型自动生成一个叫id的自增主键,哪怕你自己已经定义了主键(比如你的MemberID),它还是会偷偷加这个字段,除非你明确告诉它不要这么做。createdAt和updatedAt:这是Sequelize自带的自动时间戳功能,默认是开启的,用来自动记录数据创建和最后更新的时间,所以查询时会自动把这两个字段加到SQL里。
怎么解决这个报错?
核心就是修改Sequelize的模型定义,把默认行为关掉,让模型和你的数据库表完全匹配:
1. 修正memberlist模型定义
更新你的模型代码,明确指定主键、禁用自动时间戳,还要补上你之前漏写的CityID字段(数据库里有这个字段,模型里必须对应上):
var memberlist = db.define('members', { MemberID: { type: Sequelize.INTEGER, primaryKey: true, // 标记这个字段是主键 autoIncrement: true, // 和数据库里的auto_increment设置对应 allowNull: false // 匹配数据库的NOT NULL约束 }, FirstName: { type: Sequelize.STRING(50), // 对应数据库的varchar(50) allowNull: false }, LastName: { type: Sequelize.STRING(50), allowNull: false }, CityID: { type: Sequelize.INTEGER, allowNull: false, references: { model: 'cities', // 假设你的城市表名叫cities,根据实际情况修改 key: 'CityID' } } }, { timestamps: false, // 直接禁用自动时间戳,这样就不会生成createdAt和updatedAt了 freezeTableName: true, // 强制使用你指定的表名'members',避免Sequelize自动把表名改成复数(虽然这里你写的是members刚好匹配,但加上更保险) });
2. 修复GraphQL解析器的写法
你现在的allMembers解析器用的是旧版Sequelize语法,还有语法错误,换成现代的async/await写法更靠谱:
var root = { allMembers: async function() { try { // 用findAll()查询所有成员,而不是旧的find({}) const members = await memberlist.findAll(); return members; } catch (err) { throw new Error('获取成员列表失败:' + err.message); } } };
3. 补充City模型与关联(必须做,不然GraphQL的City字段会报错)
你的GraphQL Schema里Members类型包含CityID: City!,所以得定义City模型并建立关联,这样查询时才能正确返回城市信息:
// 先定义City模型 var city = db.define('cities', { CityID: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false }, CityName: { type: Sequelize.STRING, allowNull: false } }, { timestamps: false, freezeTableName: true }); // 建立Member和City的关联:每个Member属于一个City memberlist.belongsTo(city, { foreignKey: 'CityID', targetKey: 'CityID' });
为什么会出现这个错误?
因为Sequelize默认生成的SQL里包含了它自动添加的id、createdAt、updatedAt字段,但你的数据库表根本没有这些字段,MySQL自然就报错说找不到这些列啦~
内容的提问来源于stack exchange,提问作者januaryananda
相关产品推荐
相关产品推荐

