回送4和MySQL关系中的约束

时间:2019-09-27 00:19:37

标签: mysql loopbackjs loopback4

我正在学习Sequelize的Loopback 4,并且对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

续集:

用户:

    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;

一切都很好,那里有限制。现在有了Loopback4。

环回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;

您可能会看到,那里没有约束。难道我做错了什么?这是预期的行为吗?

2 个答案:

答案 0 :(得分:0)

这是LoopBack的一个已知缺点,请参见以下GitHub问题中的讨论:

答案 1 :(得分:0)

Loopback 4和MySQL关系中的约束

@model({
  settings: {
    foreignKeys: {
      fk_todo_todoListId: {
        name: 'fk_todo_todoListId',
        entity: 'TodoList',
        entityKey: 'id',
        foreignKey: 'todolistid',
      },
    },
  },
})
export class Todo extends Entity {
  //etc.
}

https://loopback.io/doc/en/lb4/todo-list-tutorial-sqldb.html#specify-the-foreign-key-constraints-in-todo-model