【问题标题】:Referencing a composite primary key in a Sequelize.js seed model在 Sequelize.js 种子模型中引用复合主键
【发布时间】:2019-01-28 04:24:54
【问题描述】:

Sequelize 中是否可以引用复合主键?

我正在开发一个帮助整理厨余垃圾的网络应用。餐厅将其周和月组织成“时段”,9 月的第一周将是“9.1”。对于每个时期,我需要创建一批新的成分对象,以跟踪它们在该时期的价格和数量。我认为最好将期间主键设为月和周的组合,因为这在数据库中是唯一的。 我可能会在一年后添加,但这不会改变我的问题。

我正在使用的数据库是 Postgres。

这是我的 sequelize 种子文件中的周期表模型:

.then(() => queryInterface.createTable('periods', {
      month: {
        type: Sequelize.INTEGER,
        validate: {
          max: 12,
          min: 1
        },
        unique: "monthWeekConstraint",
        primaryKey: true
      },
      week: {
        type: Sequelize.INTEGER,
        validate: {
          max: 4,
          min: 1
        },
        unique: "monthWeekConstraint",
        primaryKey: true
      },
      createdAt: {
        type: Sequelize.DATE
      },
      updtedAt: {
        type: Sequelize.DATE
      }
    }))

我想在我的 periodItems 表中引用存储在上表中的期间,我(错误地)看起来像:

.then(() => queryInterface.createTable('periodItems', {
  periodMonth: {
    type: Sequelize.INTEGER,
    references: {model: 'periods', key: 'monthWeekConstraint'}
  },
  periodWeek: {
    type: Sequelize.INTEGER,
    references: {model: 'periods', key: 'monthWeekConstraint'}
  },
  day: {
    type: Sequelize.INTEGER,
    validate: {
      min: 1,
      max: 7
    }
  },
...other irrelevant fields...
}))

我绝对是数据库的新手,所以如果我离开了,我深表歉意。我已经让其他几张桌子做我想做的事,但我已经被这个问题困住了几天。

【问题讨论】:

    标签: database postgresql sequelize.js


    【解决方案1】:

    虽然可以通过针对多个列指定primaryKey: true 在 Sequelize 中创建复合主键(正如您在上面已经完成的那样),但 Sequelize 目前不支持复合外键,因此无法引用具有复合主键的模型/表。

    有关该主题的讨论,请参阅 https://github.com/sequelize/sequelize/issues/311

    【讨论】:

    • 还是这样吗?
    • 嗨@Prof,我相信是这样,因为上面链接的 Github 问题仍然是开放和活跃的。 AFAICT 解决它的唯一方法是在所有目标表上使用单个主键列,并限制自己使用单列外键。缺点是这不允许复合外键可以处理的许多复杂的约束实施场景。
    • 啊,真可惜。最后我选择了与外键相比具有唯一性的代理键。
    • 我想知道为什么要一个复合外键?...
    • @x-yuri 我经常使用它来确保数据完整性。这可以减少可能由使用相同数据库的其他应用程序或迁移导致的错误关联。因此,如果应用程序出错,数据不会被破坏。但也可能存在其他情况。
    【解决方案2】:
    model/product.js:
    const Product = sequelize.define("product", {
      sku: { type: Sequelize.STRING, allowNull: false, primaryKey: true },
      title: { type: Sequelize.STRING, allowNull: false },
      availability: {
        type: Sequelize.STRING,
        allowNull: false,
        defaultValue: false,
      }
    });
    
    model/Attribute.js:
    const Attribute = sequelize.define("attribute", {
      key: { type: Sequelize.STRING, allowNull: false, primaryKey: true },
      productSku: { type: Sequelize.STRING, allowNull: false, primaryKey: true },
      value: { type: Sequelize.STRING, allowNull: false },
    });
    
    
    After importing to app.js:
    product.hasMany(attribute, { foreignKey: "productSku", sourceKey: "sku" });
    attribute.belongsTo(product, { foreignKey: "productSku", targetKey: "sku" });
    
    
    Explanation:
    Product.sku is exported as foreign key to Attibute.productSku. Attribute table has a composite foreign (key + productSku), and a ForeignKey(productSku) from product.sku;
    

    【讨论】:

    • 这是否正确支持复合外键?这是sequelize新增的功能吗?
    猜你喜欢
    • 1970-01-01
    • 2022-11-21
    • 1970-01-01
    • 2014-07-31
    • 1970-01-01
    • 2021-02-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-17
    相关资源
    最近更新 更多