[SQLAlchemy] synchronize_session参数详解
synchronize_session用于query在进行delete or update操作时,对session的同步策略。
- False - 不对session进行同步,直接进行delete or update操作。
- 'fetch'
在delete or update操作之前,先发一条sql到数据库获取符合条件的记录。
1 def _do_pre_synchronize(self): 2 query = self.query 3 session = query.session 4 context = query._compile_context() 5 select_stmt = context.statement.with_only_columns( 6 self.primary_table.primary_key) 7 self.matched_rows = session.execute( 8 select_stmt, 9 mapper=self.mapper, 10 params=query._params).fetchall()
在delete or update操作之后,将session的identity_map与前一步获取到的记录进行match,符合条件的就从session中删掉或更新。
1 def _do_post_synchronize(self): 2 session = self.query.session 3 target_mapper = self.query._mapper_zero() 4 for primary_key in self.matched_rows: 5 # TODO: inline this and call remove_newly_deleted 6 # once 7 identity_key = target_mapper.identity_key_from_primary_key( 8 list(primary_key)) 9 if identity_key in session.identity_map: 10 session._remove_newly_deleted( 11 [attributes.instance_state( 12 session.identity_map[identity_key] 13 )] 14 )
- 'evaluate'
在delete or update操作之前,用query中的条件直接对session的identity_map中的objects进行eval操作,将符合条件的记录下来。
1 def _do_pre_synchronize(self): 2 query = self.query 3 target_cls = query._mapper_zero().class_ 4 5 try: 6 evaluator_compiler = evaluator.EvaluatorCompiler(target_cls) 7 if query.whereclause is not None: 8 eval_condition = evaluator_compiler.process( 9 query.whereclause) 10 else: 11 def eval_condition(obj): 12 return True 13 14 self._additional_evaluators(evaluator_compiler) 15 16 except evaluator.UnevaluatableError: 17 raise sa_exc.InvalidRequestError( 18 "Could not evaluate current criteria in Python. " 19 "Specify 'fetch' or False for the " 20 "synchronize_session parameter.") 21 22 # TODO: detect when the where clause is a trivial primary key match 23 self.matched_objects = [ 24 obj for (cls, pk), obj in 25 query.session.identity_map.items() 26 if issubclass(cls, target_cls) and 27 eval_condition(obj)]
在delete or update操作之后,将符合条件的记录删除或更新。
1 def _do_post_synchronize(self): 2 self.query.session._remove_newly_deleted( 3 [attributes.instance_state(obj) 4 for obj in self.matched_objects])