knex.js 迁移创建彼此之间有关系的表失败
knex.js migrations create tables with relationship between each other fails
我找遍了所有地方,有很多示例,但没有一个是完整的或有效的。
用例:
简单的数据库结构,几个 table 和一些关系。在 docker 容器中设置节点、knex 和 pg。
一切正常。
为第一个 table (table A) 创建了迁移文件 - 好的。
添加了第二个 table (table B) 和从 table B 到 A 的 1:n 关系。一切都很好。
添加了从 table A 到 table B 的 1:n 关系。脚本出错了。
table 信息:
exports.up = function(knex) {
return knex.schema
.createTable('user', t => {
t.uuid('user_id').primary()
t.string('name', 100).notNullable()
t.string('surname', 100)
t.string('email').notNullable().unique()
t.string('password')
t
.boolean('email_confirmed')
.notNullable()
.defaultTo(false)
t
.datetime('last_login', { precision: 6 })
.defaultTo(knex.fn.now(6))
t.string('language')
t.string('newsletter')
t.timestamps(true, true)
t
.uuid('company_id')
.references('company_id')
.inTable('company')
})
.createTable('company', t => {
t.uuid('company_id').primary()
t.string('address_id')
t.string('name', 100).notNullable()
t.string('phone')
t.timestamps(true, true)
t
.uuid('owner_user_id')
.references('user_id')
.inTable('user')
})
}
错误:
migration failed with error: alter table "user" add constraint
"user_company_uuid_foreign" foreign key ("company_uuid") references
"company" ("company_id") - relation "company" does not exist
我会说它会尝试创建一个 table 并在创建第二个 table(FK 引用)之前添加外键。
关于如何解决这个问题的任何想法。
- 这不是真正的 m:n 关系。一个公司可以而且应该只有一个所有者。一个用户必须属于一个公司,否则它不可能存在。如果这无法解决,我可以将
user.company_id
字段作为一个简单的字符串 w/o 任何关系。
- 为 user_companies 使用不同的 table 就太过分了。
谢谢!
您是正确的,它试图在它所引用的 table 存在之前创建引用。最简单的方法可能是简单地延迟外键的创建,直到创建 companies
table 之后。即
exports.up = async function(knex) {
await knex.schema.createTable('user', t => {
t.uuid('user_id').primary()
t.string('name', 100).notNullable()
t.string('surname', 100)
t.string('email').notNullable().unique()
t.string('password')
t.boolean('email_confirmed')
.notNullable()
.defaultTo(false)
t.datetime('last_login', { precision: 6 })
.defaultTo(knex.fn.now(6))
t.string('language')
t.string('newsletter')
t.timestamps(true, true)
t.uuid('company_id')
});
await knex.schema.createTable('company', t => {
t.uuid('company_id').primary()
t.string('address_id')
t.string('name', 100).notNullable()
t.string('phone')
t.timestamps(true, true)
t.uuid('owner_user_id')
.references('user_id')
.inTable('user')
});
await knex.schema.table('user', t => {
t.foreign('company_id')
.references('company_id')
.inTable('company')
});
}
我找遍了所有地方,有很多示例,但没有一个是完整的或有效的。
用例: 简单的数据库结构,几个 table 和一些关系。在 docker 容器中设置节点、knex 和 pg。 一切正常。 为第一个 table (table A) 创建了迁移文件 - 好的。 添加了第二个 table (table B) 和从 table B 到 A 的 1:n 关系。一切都很好。 添加了从 table A 到 table B 的 1:n 关系。脚本出错了。
table 信息:
exports.up = function(knex) {
return knex.schema
.createTable('user', t => {
t.uuid('user_id').primary()
t.string('name', 100).notNullable()
t.string('surname', 100)
t.string('email').notNullable().unique()
t.string('password')
t
.boolean('email_confirmed')
.notNullable()
.defaultTo(false)
t
.datetime('last_login', { precision: 6 })
.defaultTo(knex.fn.now(6))
t.string('language')
t.string('newsletter')
t.timestamps(true, true)
t
.uuid('company_id')
.references('company_id')
.inTable('company')
})
.createTable('company', t => {
t.uuid('company_id').primary()
t.string('address_id')
t.string('name', 100).notNullable()
t.string('phone')
t.timestamps(true, true)
t
.uuid('owner_user_id')
.references('user_id')
.inTable('user')
})
}
错误:
migration failed with error: alter table "user" add constraint "user_company_uuid_foreign" foreign key ("company_uuid") references "company" ("company_id") - relation "company" does not exist
我会说它会尝试创建一个 table 并在创建第二个 table(FK 引用)之前添加外键。
关于如何解决这个问题的任何想法。
- 这不是真正的 m:n 关系。一个公司可以而且应该只有一个所有者。一个用户必须属于一个公司,否则它不可能存在。如果这无法解决,我可以将
user.company_id
字段作为一个简单的字符串 w/o 任何关系。 - 为 user_companies 使用不同的 table 就太过分了。
谢谢!
您是正确的,它试图在它所引用的 table 存在之前创建引用。最简单的方法可能是简单地延迟外键的创建,直到创建 companies
table 之后。即
exports.up = async function(knex) {
await knex.schema.createTable('user', t => {
t.uuid('user_id').primary()
t.string('name', 100).notNullable()
t.string('surname', 100)
t.string('email').notNullable().unique()
t.string('password')
t.boolean('email_confirmed')
.notNullable()
.defaultTo(false)
t.datetime('last_login', { precision: 6 })
.defaultTo(knex.fn.now(6))
t.string('language')
t.string('newsletter')
t.timestamps(true, true)
t.uuid('company_id')
});
await knex.schema.createTable('company', t => {
t.uuid('company_id').primary()
t.string('address_id')
t.string('name', 100).notNullable()
t.string('phone')
t.timestamps(true, true)
t.uuid('owner_user_id')
.references('user_id')
.inTable('user')
});
await knex.schema.table('user', t => {
t.foreign('company_id')
.references('company_id')
.inTable('company')
});
}