Odoo12修改stock.picking的batch_id触发CacheMiss错误求助
stock.picking's batch_id I've run into this exact kind of cache issue in Odoo before, so let's break down what's causing your error and how to fix it.
What's Causing the CacheMiss?
Your error points to stock.picking.batch(31,).picking_batch_moves missing from the cache, and there are two key culprits here:
- Bypassing ORM with raw SQL: Your compute method uses
self.env.cr.executeto fetch data, which skips Odoo's built-in cache tracking. When you update a picking'sbatch_id, Odoo tries to refresh the batch's computed fields but can't sync the cache with the raw database changes. - Incorrect recordset initialization: Inside your batch loop, you set
linked = batch_moves_obj(the entire model object) instead of an empty recordset. This leads to invalid data being assigned topicking_batch_moves, confusing Odoo's cache system.
Step-by-Step Fix
Let's rewrite the compute method to use Odoo's ORM properly and fix the recordset handling:
1. Replace Raw SQL with ORM Queries
Using ORM ensures Odoo tracks data changes and maintains cache consistency. Here's the updated compute method:
@api.depends("picking_ids", "picking_ids.move_lines") def _compute_picking_get_batch_lines(self): batch_moves_obj = self.env["stock.picking.batch.move"] for batch in self: if isinstance(batch.id, models.NewId): continue # Fetch all moves linked to this batch via pickings moves = self.env['stock.move'].search([ ('picking_id.batch_id', '=', batch.id) ]) # Group moves by product, UOM, locations, state, and picking type grouped_data = {} for move in moves: group_key = ( move.product_id.id, move.product_uom.id, move.location_id.id, move.location_dest_id.id, move.state, move.picking_type_id.id ) if group_key not in grouped_data: grouped_data[group_key] = { 'product_id': move.product_id.id, 'product_uom_id': move.product_uom.id, 'location_id': move.location_id.id, 'location_dest_id': move.location_dest_id.id, 'state': move.state, 'picking_type_id': move.picking_type_id.id, 'product_uom_qty': 0.0, 'move_ids': [] } grouped_data[group_key]['product_uom_qty'] += move.product_uom_qty grouped_data[group_key]['move_ids'].append(move.id) # Get existing batch moves for this batch existing_batch_moves = batch_moves_obj.search([("batch_id", "=", batch.id)]) linked = self.env["stock.picking.batch.move"] # Start with empty recordset for group in grouped_data.values(): line_data = { "batch_id": batch.id, "product_id": group['product_id'], "product_uom_id": group['product_uom_id'], "location_id": group['location_id'], "location_dest_id": group['location_dest_id'], "state": group['state'], "picking_type_id": group['picking_type_id'], "product_uom_qty": group['product_uom_qty'], "move_lines": [(6, 0, group['move_ids'])], } # Find matching existing batch move matched = existing_batch_moves.filtered( lambda x: (x.product_id.id == group['product_id'] and x.product_uom_id.id == group['product_uom_id'] and x.location_id.id == group['location_id'] and x.location_dest_id.id == group['location_dest_id'] and x.state == group['state']) ) if matched.exists(): matched.write(line_data) linked += matched else: new_line = batch_moves_obj.create(line_data) linked += new_line # Clean up old batch moves that no longer have matching moves to_unlink = existing_batch_moves - linked if to_unlink: to_unlink.unlink() # Assign the valid recordset to the batch field batch.picking_batch_moves = linked
2. Remove recompute=False Context
You were using with_context(recompute=False) when creating/writing batch moves, which prevents Odoo from updating related computed fields and cache. Removing this ensures the cache stays in sync with your data changes.
3. Add Cleanup Logic
The new code includes a step to delete old batch moves that don't have any matching stock moves anymore. This keeps your data consistent and avoids orphaned records that could also cause cache issues.
Why This Works
- ORM Usage: Odoo's ORM automatically tracks all data operations, so when you update a picking's
batch_id, the cache is refreshed correctly for the related batch. - Proper Recordset Handling: Initializing
linkedas an empty recordset ensures you only assign valid, batch-specific moves topicking_batch_moves. - Cache Consistency: By letting Odoo manage data changes instead of bypassing it with raw SQL, you eliminate the cache mismatch that caused the
CacheMisserror.
内容的提问来源于stack exchange,提问作者m3asmi

