node.js - Sequelize asociace nefungují s Typescriptem
Poskytnu nějaký kód, protože může být těžké sledovat, co se děje. V podstatě moje Express API nevrací žádná spojení, i když moje databáze si myslí, že existují.
Stručně a rychle: Snažím se získat asociaci mezi dvěma modely Users a Donations, jeden-k-mnoha.
Zde je můj uživatelský model (zjednodušený):
import { Sequelize, DataTypes, Model, BuildOptions, Optional, Association, } from "sequelize";
// These are all the attributes in the User model
export interface UserAttributes {
id: number;
firstName: string;
lastName: string;
createdAt?: Date;
updatedAt?: Date;
}
// Optional properties, sequelize has the ability to fill these in itself
interface UserCreationAttributes
extends Optional<
UserAttributes,
"id"
> {}
// Creates the final type interface for the UserModel
export interface UserModel
extends Model<UserAttributes, UserCreationAttributes>,
UserAttributes {}
// Creates the User class as an extended type of a general model and UserModel
export class User extends Model<UserModel, UserAttributes> {
// Public properties
public id!: number;
public firstName!: string;
public lastName!: string;
// Timestamps
public readonly createdAt!: Date;
public readonly updatedAt!: Date;
// Associations
public static associations: {
donations: Association<User, Donation>;
};
}
// Creates a static type used for our factory function
export type UserStatic = typeof Model & {
new (values?: object, options?: BuildOptions): UserModel;
};
// This function is responsible for generating the "User" model
export function userFactory(sequelize: Sequelize): UserStatic {
return <UserStatic>sequelize.define(
"users",
{
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
firstName: {
type: new DataTypes.STRING(128),
allowNull: false,
validate: { notEmpty: true },
},
lastName: {
type: DataTypes.STRING,
allowNull: false,
validate: { notEmpty: true },
},
});
}
Dárcovský model je nastaven z velké části stejným způsobem, nechci vás zaplavovat kódem, takže přejdu rovnou k části, kde provádím asociace.
// Import the factory functions and sequelize instance, called "db" here
import { donationFactory } from "./Donation";
import { userFactory } from "./User";
import { db } from "../db";
// The Factory functions expect a Sequelize instance as a parameter
const User = userFactory(db);
const Donation = donationFactory(db);
const DonationsRecipients = donationsRecipientsFactory(db);
// Associations
Donation.belongsTo(User);
User.hasMany(Donation);
// Export model
export const model = {
Donation,
DonationsRecipients,
User,
};
Dobře, takže můžete vidět, že zde deklaruji velmi jednoduchý vztah Jeden-k-Mnoha mezi modely Donation a User. Níže vám ukážu svůj kód pro mou express trasu.
// Get all donors
userGetRoutes.get("/donors", async (req, res, next) => {
try {
const users = await User.findAll({
where: { isDonor: true },
include: [{ model: Donation }],
});
res.status(200).send(users);
} catch (error) {
next(error);
}
});
Ale já dostanu jen toto!!! Zahrnuté dary tam nejsou... Nemohu se dostat k objektům darů
A co je ještě divnější, je, že Postico si myslí, že VZTAH existuje. Poznáte to podle toho, že když kliknete na malou tabulku v mém modelu Donation, objeví se propojený uživatel (Monica Moneybags).
Tak... co se děje??
EDIT: Dobře, takže jsem udělal nějaký pokrok. Podařilo se mi, aby uživatelské instance mohly volat „getDonations()“ a další magické metody, které skutečně vracejí dary.
Abych to udělal, upravil jsem své třídy UserModel a User takto:
import {
Sequelize,
DataTypes,
Model,
BuildOptions,
Optional,
Association,
HasManyGetAssociationsMixin,
HasManyAddAssociationMixin,
HasManyHasAssociationMixin,
HasManyCountAssociationsMixin,
HasManyCreateAssociationMixin,
} from "sequelize";
/ Creates the final type interface for the UserModel
export interface UserModel
extends Model<UserAttributes, UserCreationAttributes>,
UserAttributes {
donations: DonationModel[];
getDonations(): HasManyGetAssociationsMixin<Donation>; // Note the null assertions!
addDonation(): HasManyAddAssociationMixin<Donation, number>;
hasDonation(): HasManyHasAssociationMixin<Donation, number>;
countDonations(: HasManyCountAssociationsMixin;
createDonation(): HasManyCreateAssociationMixin<Donation>;
}
// Creates the Donation classs as an extended type of a general model and UserModel
export class User extends Model<UserModel, UserAttributes> {
// Public properties
public id!: number;
public firstName!: string;
public lastName!: string;
// Timestamps
public readonly createdAt!: Date;
public readonly updatedAt!: Date;
// Associations
//
// Since TS cannot determine model association at compile time
// we have to declare them here purely virtually
// these will not exist until `Model.init` was called.
public getDonations!: HasManyGetAssociationsMixin<Donation>; // Note the null assertions!
public addDonation!: HasManyAddAssociationMixin<Donation, number>;
public hasDonation!: HasManyHasAssociationMixin<Donation, number>;
public countDonations!: HasManyCountAssociationsMixin;
public createDonation!: HasManyCreateAssociationMixin<Donation>;
public readonly donations?: Donation[]; // Note this is optional since it's only populated when explicitly requested in code
public static associations: {
donations: Association<User, Donation>;
};
}
Přesto však inkluze nefungují na volaných jako:
const users = await User.findOne({
where: { isDonor: true },
include: [{ model: Donation }],
});
Vrací to jen prázdné pole v vlastnosti „donations“ :/

