Register all persistent objects from a flush. This is used both for pending objects moving to the persistent state as well as already persistent objects.
(self, states: Set[InstanceState[Any]])
| 3341 | ) |
| 3342 | |
| 3343 | def _register_persistent(self, states: Set[InstanceState[Any]]) -> None: |
| 3344 | """Register all persistent objects from a flush. |
| 3345 | |
| 3346 | This is used both for pending objects moving to the persistent |
| 3347 | state as well as already persistent objects. |
| 3348 | |
| 3349 | """ |
| 3350 | |
| 3351 | pending_to_persistent = self.dispatch.pending_to_persistent or None |
| 3352 | for state in states: |
| 3353 | mapper = _state_mapper(state) |
| 3354 | |
| 3355 | # prevent against last minute dereferences of the object |
| 3356 | obj = state.obj() |
| 3357 | if obj is not None: |
| 3358 | instance_key = mapper._identity_key_from_state(state) |
| 3359 | |
| 3360 | if ( |
| 3361 | _none_set.intersection(instance_key[1]) |
| 3362 | and not mapper.allow_partial_pks |
| 3363 | or _none_set.issuperset(instance_key[1]) |
| 3364 | ): |
| 3365 | raise exc.FlushError( |
| 3366 | "Instance %s has a NULL identity key. If this is an " |
| 3367 | "auto-generated value, check that the database table " |
| 3368 | "allows generation of new primary key values, and " |
| 3369 | "that the mapped Column object is configured to " |
| 3370 | "expect these generated values. Ensure also that " |
| 3371 | "this flush() is not occurring at an inappropriate " |
| 3372 | "time, such as within a load() event." |
| 3373 | % state_str(state) |
| 3374 | ) |
| 3375 | |
| 3376 | if state.key is None: |
| 3377 | state.key = instance_key |
| 3378 | elif state.key != instance_key: |
| 3379 | # primary key switch. use safe_discard() in case another |
| 3380 | # state has already replaced this one in the identity |
| 3381 | # map (see test/orm/test_naturalpks.py ReversePKsTest) |
| 3382 | self.identity_map.safe_discard(state) |
| 3383 | trans = self._transaction |
| 3384 | assert trans is not None |
| 3385 | if state in trans._key_switches: |
| 3386 | orig_key = trans._key_switches[state][0] |
| 3387 | else: |
| 3388 | orig_key = state.key |
| 3389 | trans._key_switches[state] = ( |
| 3390 | orig_key, |
| 3391 | instance_key, |
| 3392 | ) |
| 3393 | state.key = instance_key |
| 3394 | |
| 3395 | # there can be an existing state in the identity map |
| 3396 | # that is replaced when the primary keys of two instances |
| 3397 | # are swapped; see test/orm/test_naturalpks.py -> test_reverse |
| 3398 | old = self.identity_map.replace(state) |
| 3399 | if ( |
| 3400 | old is not None |
no test coverage detected