指定insertGraph中列仅插入不更新,解决未允许关联报错问题
Let's break down your problem and walk through the solutions step by step:
1. Fix the Invalid allowInsert Syntax
First, your current allowInsert syntax is incorrect—this is likely the root cause of the unallowed relation error. Objection.js requires specific formatting to target nested relation columns. You have two valid options:
Option A: Dot Notation
Use dot syntax to reference nested columns directly:
ModelName.query(trx) .allowInsert([ 'subrelation2.columnToPopulate1', 'subrelation2.columnToPopulate2' ]) .insertGraph(data);
Option B: Object Syntax (More Readable for Nested Relations)
Use an object to explicitly define allowed columns per relation:
ModelName.query(trx) .allowInsert({ subrelation2: ['columnToPopulate1', 'columnToPopulate2'] }) .insertGraph(data);
By fixing this syntax, you're telling Objection.js that the subrelation2 relation is permitted for insertion, along with the specific columns you want to populate.
2. Let Objection.js Handle the Foreign Key Automatically
You don't need to include or allow the foreign key column (foreignId) in your allowInsert configuration. When inserting nested relations via insertGraph, Objection.js automatically sets the foreign key value to match the parent record's ID—assuming your model relations are properly defined (e.g., belongsTo, hasMany).
- Remove the foreign key from your input data: Don't include
foreignIdin thedataobject you pass toinsertGraph. - Don't add it to
allowInsert: Let Objection manage this column internally to avoid conflicts.
3. Implement Insert-Only Columns (Prevent Upserts for Specific Columns)
If you want certain columns to be populated only on insert (not updated during upserts), you'll need to separate insert and upsert permissions using allowInsert and allowUpsert, then configure the onConflict behavior:
Example with UpsertGraph
ModelName.query(trx) // Allow all desired columns for insert .allowInsert({ subrelation2: ['columnToPopulate1', 'columnToPopulate2', 'insertOnlyColumn'] }) // Exclude insert-only columns from updates .allowUpsert({ subrelation2: ['columnToPopulate1', 'columnToPopulate2'] }) .upsertGraph(data, { onConflict: (builder) => { builder.onConflict('id') // Replace with your unique constraint .doUpdateSet((updateBuilder) => { // Only update columns allowed in allowUpsert updateBuilder.set('columnToPopulate1', updateBuilder.ref('excluded.columnToPopulate1')) .set('columnToPopulate2', updateBuilder.ref('excluded.columnToPopulate2')); }); } });
This ensures that insertOnlyColumn is only set when creating new records, and ignored when updating existing ones.
Key Notes
- Double-check your model relations: Ensure the parent-child relationship is correctly defined (e.g.,
belongsToin the child model pointing to the parent) so Objection can auto-manage the foreign key. - Avoid using
relation2.*unless necessary: Your goal to retain integrity checks is valid—using explicit column lists prevents accidental overwrites of sensitive or auto-managed columns.
内容的提问来源于stack exchange,提问作者IdiakosE Sunday

