2626
2727"""
2828
29+ import logging
2930from typing import (
3031 Dict ,
3132 Generator ,
3738 Union ,
3839)
3940
40- # noinspection PyProtectedMember
4141from sqlalchemy import inspect
4242from sqlalchemy .orm .base import class_mapper
4343from sqlalchemy .orm .mapper import Mapper
5151from cardinal_pythonlib .classes import gen_all_subclasses
5252from cardinal_pythonlib .enumlike import OrderedNamespace
5353from cardinal_pythonlib .dicts import reversedict
54- from cardinal_pythonlib .logs import get_brace_style_log_with_null_handler
5554
5655if TYPE_CHECKING :
5756 from sqlalchemy .orm .state import InstanceState
5857 from sqlalchemy .sql .schema import Table
5958
60- log = get_brace_style_log_with_null_handler (__name__ )
59+ log = logging . getLogger (__name__ )
6160
6261
6362# =============================================================================
@@ -253,7 +252,7 @@ def walk_orm_tree(
253252 continue
254253 seen .add (obj )
255254 if debug :
256- log .debug ("walk: yielding {!r}" , obj )
255+ log .debug (f "walk: yielding { obj !r} " )
257256 yield obj
258257 insp = inspect (obj ) # type: InstanceState
259258 for (
@@ -272,10 +271,10 @@ def walk_orm_tree(
272271 continue
273272 # Process relationship
274273 if debug :
275- log .debug ("walk: following relationship {}" , relationship )
274+ log .debug (f "walk: following relationship { relationship } " )
276275 related = getattr (obj , attrname )
277276 if debug and related :
278- log .debug ("walk: queueing {!r}" , related )
277+ log .debug (f "walk: queueing { related !r} " )
279278 if relationship .uselist :
280279 stack .extend (related )
281280 elif related is not None :
@@ -331,20 +330,20 @@ def copy_sqla_object(
331330 prohibited |= fk_keys
332331 prohibited |= set (omit_attrs )
333332 if debug :
334- log .debug ("copy_sqla_object: skipping: {}" , prohibited )
333+ log .debug (f "copy_sqla_object: skipping: { prohibited } " )
335334 for k in [
336335 p .key for p in mapper .iterate_properties if p .key not in prohibited
337336 ]:
338337 try :
339338 value = getattr (obj , k )
340339 if debug :
341340 log .debug (
342- "copy_sqla_object: processing attribute {} = {}" , k , value
341+ f "copy_sqla_object: processing attribute { k } = { value } "
343342 )
344343 setattr (newobj , k , value )
345344 except AttributeError :
346345 if debug :
347- log .debug ("copy_sqla_object: failed attribute {}" , k )
346+ log .debug (f "copy_sqla_object: failed attribute { k } " )
348347 pass
349348 return newobj
350349
@@ -428,8 +427,8 @@ def rewrite_relationships(
428427 if related_table_name in skip_table_names :
429428 if debug :
430429 log .debug (
431- "Skipping relationship for related table {!r}" ,
432- related_table_name ,
430+ f "Skipping relationship for related table "
431+ f" { related_table_name !r } "
433432 )
434433 continue
435434 # The relationship is an abstract object (so getting the
@@ -439,17 +438,25 @@ def rewrite_relationships(
439438 # rel_key = rel.key # type: str
440439 # ... but also available from the mapper as attrname, above
441440 related_old = getattr (oldobj , attrname )
442- if rel_prop .uselist :
443- related_new = [objmap [r ] for r in related_old ]
444- elif related_old is not None :
445- related_new = objmap [related_old ]
446- else :
447- related_new = None
441+ try :
442+ if rel_prop .uselist :
443+ related_new = [objmap [r ] for r in related_old ]
444+ elif related_old is not None :
445+ related_new = objmap [related_old ]
446+ else :
447+ related_new = None
448+ except KeyError as e :
449+ # Often long messages; caps makes it slightly easier to read.
450+ log .critical (
451+ f"WHILE PROCESSING { oldobj = !r} , AN ATTRIBUTE FROM "
452+ f"{ related_old = !r} , ACCESSED AS oldobj.{ attrname } , "
453+ f"IS MISSING FROM { objmap = !r} . ERROR WAS: KeyError: { e } "
454+ )
455+ raise
448456 if debug :
449457 log .debug (
450- "rewrite_relationships: relationship {} -> {}" ,
451- attrname ,
452- related_new ,
458+ f"rewrite_relationships: relationship "
459+ f"{ attrname } -> { related_new } "
453460 )
454461 setattr (newobj , attrname , related_new )
455462
@@ -508,7 +515,7 @@ def deepcopy_sqla_objects(
508515 for startobj in startobjs :
509516 for oldobj in walk_orm_tree (startobj , seen = seen , debug = debug_walk ):
510517 if debug :
511- log .debug ("deepcopy_sqla_objects: copying {}" , oldobj )
518+ log .debug (f "deepcopy_sqla_objects: copying { oldobj } " )
512519 newobj = copy_sqla_object (oldobj , omit_pk = True , omit_fk = True )
513520 # Don't insert the new object into the session here; it may trigger
514521 # an autoflush as the relationships are queried, and the new
@@ -525,7 +532,7 @@ def deepcopy_sqla_objects(
525532 log .debug ("deepcopy_sqla_objects: pass 2: set relationships" )
526533 for oldobj , newobj in objmap .items ():
527534 if debug :
528- log .debug ("deepcopy_sqla_objects: newobj: {}" , newobj )
535+ log .debug (f "deepcopy_sqla_objects: newobj: { newobj } " )
529536 rewrite_relationships (oldobj , newobj , objmap , debug = debug_rewrite_rel )
530537
531538 # Now we can do session insert.
0 commit comments