Я вхожу в Loopback 4, пришедший из Sequelize и с небольшим опытом работы с TypeORM.
Мой вопрос заключается в том, почему в Loopback 4 отношения не получают ограничений.Я видел https://loopback.io/doc/en/lb4/todo-list-tutorial-sqldb.html#specify-the-foreign-key-constraints-in-todo-model,, но я не понимаю, почему он не делает это автоматически, или если я делаю что-то не так.
Давайте посмотрим пример с теми же моделями для трехORMS: модель User
, которая может иметь множество Post
:
User --* Post
Sequelize:
Пользователь:
const User = sequelize.define(
'User',
{
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
primaryKey: true,
allowNull: false,
},
name: {
type: Sequelize.STRING,
},
},
{}
);
User.associate = function(models) {
User.hasMany(models.Post, { onDelete: 'CASCADE' });
};
Сообщение:
const Post = sequelize.define(
'Post',
{
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
primaryKey: true,
allowNull: false,
},
title: {
type: Sequelize.STRING,
},
text: {
type: Sequelize.TEXT,
},
},
{}
);
Post.associate = function(models) {
Post.belongsTo(models.User, { onDelete: 'CASCADE' });
};
Результат в MYSQL:
CREATE TABLE IF NOT EXISTS `test_sequelize`.`Users` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB
AUTO_INCREMENT = 3
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `test_sequelize`.`Posts` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`title` VARCHAR(255) NULL DEFAULT NULL,
`text` TEXT NULL DEFAULT NULL,
`UserId` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `UserId` (`UserId` ASC) ,
CONSTRAINT `posts_ibfk_1`
FOREIGN KEY (`UserId`)
REFERENCES `test_sequelize`.`Users` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB
AUTO_INCREMENT = 4
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_unicode_ci;
Хорошо, ограничения есть.
Теперь давайте попробуем с TypeORM:
TypeORM:
Пользователь:
import { Post } from './Post';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: string;
@Column()
name: string;
@OneToMany(type => Post, post => post.user, { onDelete: 'CASCADE' })
posts: Post[];
}
Сообщение:
import { User } from './User';
import { PostHasTag } from './PostHasTag';
import { Tag } from './Tag';
@Entity()
export class Post {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column({ type: 'text' })
text: string;
@ManyToOne(type => User, user => user.posts)
user: User;
}
И это результат в MySQL:
CREATE TABLE IF NOT EXISTS `test_typeorm`.`user` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB
AUTO_INCREMENT = 3
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `test_typeorm`.`post` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`title` VARCHAR(255) NOT NULL,
`text` TEXT NOT NULL,
`userId` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `FK_5c1cf55c308037b5aca1038a131` (`userId` ASC) ,
CONSTRAINT `FK_5c1cf55c308037b5aca1038a131`
FOREIGN KEY (`userId`)
REFERENCES `test_typeorm`.`user` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
AUTO_INCREMENT = 4
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_unicode_ci;
Все хорошо, ограничения там.Теперь с Loopback 4.
Loopback 4:
Модели, репозитории, контроллеры и связи создаются клиентом Cli, но я опубликую только модели:
Пользователь:
import {Post} from './post.model';
@model({settings: {}})
export class User extends Entity {
@property({
type: 'number',
id: true,
generated: true,
})
id?: number;
@property({
type: 'string',
required: true,
})
name: string;
@hasMany(() => Post)
posts: Post[];
constructor(data?: Partial<User>) {
super(data);
}
}
export interface UserRelations {
// describe navigational properties here
}
export type UserWithRelations = User & UserRelations;
Сообщение:
import {Entity, model, property} from '@loopback/repository';
@model({settings: {}})
export class Post extends Entity {
@property({
type: 'number',
id: true,
generated: true,
})
id?: number;
@property({
type: 'string',
required: true,
})
title: string;
@property({
type: 'string',
})
text?: string;
@property({
type: 'number',
})
userId?: number;
constructor(data?: Partial<Post>) {
super(data);
}
}
export interface PostRelations {
// describe navigational properties here
}
export type PostWithRelations = Post & PostRelations;
И MySQL:
CREATE TABLE IF NOT EXISTS `test_loopback`.`Post` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`title` VARCHAR(512) NOT NULL,
`text` VARCHAR(512) NULL DEFAULT NULL,
`userId` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB
AUTO_INCREMENT = 2
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `test_loopback`.`User` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(512) NOT NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB
AUTO_INCREMENT = 2
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_unicode_ci;
И, как вы можете видеть, там нет никаких ограничений,Я делаю что-то неправильно?Это ожидаемое поведение?