Javascript 如何使用Postgresql、Knex.js和Objective.js以及HasonRelation向具有关系的外部对象插入默认值?
我正在使用Javascript 如何使用Postgresql、Knex.js和Objective.js以及HasonRelation向具有关系的外部对象插入默认值?,javascript,node.js,postgresql,knex.js,objection.js,Javascript,Node.js,Postgresql,Knex.js,Objection.js,我正在使用Postgresql、Knex.js和objective.js设置简单的API。我用“location”属性创建了用户模型。此“位置”属性是另一个表。如何在“location”属性中使用默认值“city”和“country”将该用户插入数据库 我已经尝试在模型本身中使用“static getjsonSchema”,在mutation中使用“allowInsert”方法,但是当我获取创建该用户时,“location”仍然是“null” 假设我们有用户迁移表: exports.up = k
Postgresql
、Knex.j
s和objective.js
设置简单的API。我用“location”属性创建了用户模型。此“位置”属性是另一个表。如何在“location”属性中使用默认值“city”和“country”将该用户插入数据库
我已经尝试在模型本身中使用“static getjsonSchema
”,在mutation中使用“allowInsert
”方法,但是当我获取创建该用户时,“location”仍然是“null”
假设我们有用户迁移表:
exports.up = knex =>
knex.schema.createTable('users', table => {
table.increments('id').primary();
table
.string('email')
.unique()
.notNullable();
table.string('firstName').notNullable();
table.string('lastName').notNullable();
table.string('password').notNullable();
});
exports.down = knex => knex.schema.dropTable('users');
我们有位置表:
exports.up = knex =>
knex.schema.createTable('locations', table => {
table.increments('id').primary();
table.string('country').defaultTo('USA');
table.string('city').defaultTo('San Francisco');
table
.integer('user_id')
.references('id')
.inTable('users')
.onUpdate('CASCADE')
.onDelete('CASCADE');
});
exports.down = knex => knex.schema.dropTable('locations');
这里是带有objective.js的用户模型:
export default class User extends Model {
static get tableName() {
return 'users';
}
// wrong probably
static get jsonSchema() {
return {
type: 'object',
properties: {
location: {
type: 'object',
properties: {
city: {
type: 'string',
default: 'Los Angeles',
},
country: {
type: 'string',
default: 'USA',
},
},
},
},
};
}
fullName() {
return `${this.firstName} ${this.lastName}`;
}
static get relationMappings() {
return {
location: {
relation: Model.HasOneRelation,
modelClass: Location,
join: {
from: 'users.id',
to: 'locations.user_id',
},
},
};
}
}
和位置模型:
export default class Location extends Model {
static get tableName() {
return 'locations';
}
static get relationMappings() {
return {
user: {
relation: Model.BelongsToOneRelation,
modelClass: `${__dirname}/User`,
join: {
from: 'locations.user_id',
to: 'users.id',
},
},
};
}
}
我创建新用户时的变异:
// ...
const payload = {
email,
firstName,
lastName,
password: hash,
};
const newUser = await User.query()
.allowInsert('[user, location]')
.insertAndFetch(payload);
// ...
在最后的查询中:
// ...
User.query()
.eager('location')
.findOne({ email });
// ...
从用户的查询中,我希望看到具有locatoin属性和默认值的对象。例如:
{
email: 'jacklondon@gmail.com',
firstName: 'Jack',
fullName: 'Jack London',
id: '1',
lastName: 'London',
location: {
city: 'San Francisco',
country: 'USA',
},
userName: 'jacklondon1',
__typename: 'User',
}
那么,我在这么简单的操作中犯了什么错误?一对一的解决方案
我认为问题的一部分是您的allow insert包含了user
对象。您不应该在允许插入中包含用户
,因为它是隐式的,因为您在用户
模型()上。您遇到的另一个问题是,您试图使用insertAndFetch
方法<插入图形时不能使用代码>插入和提取。您需要使用insertGraph
方法插入图形()。由于您使用的是Postgres,因此可以链接returning(*)
方法,它将返回结果而无需额外查询()。最后,由于您要求一对一的关系,因此每次都必须指定一个城市和国家。Objective不知道需要创建新行而不指定它(即使您已将数据库配置为具有默认值)。我为你做到这一点的方法是使用
思考的另一个想法
我不知道为什么用户和位置之间有一对一的关系。既然已经是一对一了,为什么不让城市、州和国家成为用户表的一部分呢
然而,我认为您真正想要的是用户和位置之间的一对多关系。一个位置有多个用户。这将通过减少数据库中的重复数据量使您陷入困境,因为您不会在相同的位置为每个用户复制城市/国家
如果您只是在学习异议,我建议您阅读中的图形。
allowInsert
使用insertGraph
方法设置允许插入的关系树。嵌套关系在insertAndFetch
方法中不可用。如果您怀疑jsonSchema
是错误的,我会将其注释出来以供测试。
const createNewuser = async (email, firstName, lastName, hash, city = 'Los Angeles', country = 'USA') => {
const newUser = await User
.query()
.insertGraph({
email,
firstName,
lastName,
password: hash,
location: {
city: city,
country: country
}
})
.returning('*');
return newUser;
}