【发布时间】:2021-01-22 17:10:09
【问题描述】:
我正在测试 sequelize(使用 typescript)来替换 typeorm。 但是,我正在努力以正确的格式从数据库中获取数据。 “正确格式”是指逐行记录作为一个普通对象,它基本上表示该类的一个实例。(检查图片与预期结果) 下面是一个自显式的简单代码。球队有几个球员,一个球员属于一个球队。在 postgres 表中,有 2 支球队,第一支球队有 3 名球员,第二支球队有 2 名球员。 与 postgres 的连接选项很简单。
"pg": "^8.3.3",
"pg-hstore": "^2.3.3",
"sequelize": "^6.3.5",
"typescript": "^4.0.2"
import { DataTypes, Model, Sequelize } from "sequelize";
import { createDbConnection } from "./DbConnections";
interface ITeamAttributes {
id: number;
teamName: string;
}
type ITeamCreationAttributes = Partial<ITeamAttributes> & { id: number };
class Team
extends Model<ITeamAttributes, ITeamCreationAttributes>
implements ITeamAttributes {
public id: number;
public teamName: string;
public teamPlayers: Array<Player>;
static defineModel(
dbConnection: Sequelize
): Model<ITeamAttributes, ITeamCreationAttributes> {
const table = this.init<Team>(
{
id: {
type: DataTypes.INTEGER,
allowNull: false,
autoIncrementIdentity: true,
primaryKey: true,
},
teamName: {
type: DataTypes.STRING(255),
allowNull: false,
defaultValue: "",
},
},
{
sequelize: dbConnection,
tableName: "team",
}
);
return table;
}
static defineRelations(): void {
Team.hasMany(Player, {
sourceKey: "id",
foreignKey: "teamId",
as: "teamPlayers",
});
}
}
interface IPlayerAttributes {
id: number;
playerName: string;
}
type IPlayerCreationAttributes = Partial<IPlayerAttributes> & { id: number };
class Player
extends Model<IPlayerAttributes, IPlayerCreationAttributes>
implements IPlayerAttributes {
public id: number;
public playerName: string;
public playerTeam: Team;
public static defineModel(
dbConnection: Sequelize
): Model<IPlayerAttributes, IPlayerCreationAttributes> {
const table = this.init<Player>(
{
id: {
type: DataTypes.INTEGER,
allowNull: false,
autoIncrementIdentity: true,
primaryKey: true,
},
playerName: {
type: DataTypes.STRING(255),
allowNull: false,
defaultValue: "",
},
},
{
sequelize: dbConnection,
tableName: "player",
}
);
return table;
}
public static defineRelations(): void {
Player.belongsTo<Player, Team>(Team, {
foreignKey: "teamId",
targetKey: "id",
as: "playerTeam",
});
}
}
const main = async (): Promise<void> => {
const dbConnection: Sequelize = createDbConnection();
if (dbConnection.authenticate()) {
Player.defineModel(dbConnection);
Team.defineModel(dbConnection);
// relations to be defined after all Model definition
Player.defineRelations();
Team.defineRelations();
await dbConnection.sync();
const teams: Array<Team> = await Team.findAll<Team>({
include: [{ association: "teamPlayers" }],
});
const players: Array<Player> = await Player.findAll<Player>({
include: [{ association: "playerTeam" }],
});
console.log(teams);
console.log(players);
console.log(teams.map((team) => team.get()));
console.log(players.map((player) => player.get()));
const tt = JSON.parse(JSON.stringify(teams, null, 2)) as Team[];
const pp = JSON.parse(JSON.stringify(players, null, 2)) as Player[];
console.log(tt, pp);
tt.map((t) => t.teamPlayers.map((p) => console.log(p.playerName)));
} else {
console.log("not connected to database");
}
};
main();
问题是,如果表正在这样做,那么唯一获取数据作为真实实例的方法:
const tt = JSON.parse(JSON.stringify(teams, null, 2)) as Team[];
const pp = JSON.parse(JSON.stringify(players, null, 2)) as Player[];
其他 console.log 没有将记录作为普通对象返回。
我试图将选项{raw:true} 添加到findAll 调用中,但这是最糟糕的。获得团队时,不是每个团队都收到一组球员的记录(所以 2 条记录),结果是平淡无奇。每对 Team/Player 有一个记录,因此 2*3 = 6 个记录。
解决办法是什么?因为应用JSON.STRINGIFY 和JSON.PARSE 是一种糟糕的方式。
问候
[编辑]
这里是findAll<Team>()的结果,这不是Team的数组
这是findAll<Team>({raw:true}) 的结果。每个团队/球员有一个记录。预期结果是每个团队有一个记录,其中包含一组玩家
这是findAll<Team>() 和findAll<Player>() 的预期结果。 Player 数组中每个 Team 有一个记录,每个 Player 都有他的团队信息。这个结果是通过应用JSON.parse(JSON.stringify(teams, null, 2)) as Team[] 和JSON.parse(JSON.stringify(players, null, 2)) as Player[]得到的
【问题讨论】: