Changeset - 26250171defd
[Not reviewed]
0 1 0
Lance Edgar (lance) - 12 years ago 2012-10-05 06:28:56
lance@edbob.org
fix foreign key uuid handling in record_changes()
1 file changed with 41 insertions and 2 deletions:
0 comments (0 inline, 0 general)
rattail/db/__init__.py
Show inline comments
 
@@ -27,14 +27,18 @@
 
"""
 

	
 
import logging
 
import warnings
 

	
 
from sqlalchemy.event import listen
 
from sqlalchemy.orm import object_mapper, RelationshipProperty
 

	
 
import edbob
 

	
 
import rattail
 

	
 

	
 
ignore_role_changes = None
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
@@ -61,9 +65,34 @@ def before_flush(session, flush_context, instances):
 
        if not hasattr(instance, 'uuid'):
 
            return
 

	
 
        # Ignore Role instances, if so configured.
 
        if ignore_role_changes and isinstance(instance, edbob.Role):
 
            return
 

	
 
        # Provide an UUID value, if necessary.
 
        if not instance.uuid:
 
            instance.uuid = edbob.get_uuid()
 

	
 
            # If the 'uuid' column is actually a foreign key to another
 
            # table...well, then we can't just generate a new value for it.
 
            # Instead we must traverse the relationship and fetch the existing
 
            # foreign key value...
 

	
 
            mapper = object_mapper(instance)
 
            uuid = mapper.columns['uuid']
 
            if uuid.foreign_keys:
 

	
 
                for prop in mapper.iterate_properties:
 
                    if (isinstance(prop, RelationshipProperty)
 
                        and len(prop.remote_side) == 1
 
                        and prop.remote_side[0].key == 'uuid'):
 

	
 
                        instance.uuid = getattr(instance, prop.key).uuid
 
                        break
 
                assert instance.uuid
 

	
 
            # ...but if there is no foreign key, just generate a new UUID.
 
            else:
 
                instance.uuid = edbob.get_uuid()
 

	
 
        # Record the change.
 
        change = session.query(rattail.Change).get(
 
@@ -105,5 +134,15 @@ def init(config):
 
    from rattail.db.extension import enum
 
    edbob.graft(rattail, enum)
 

	
 
    if config.get('rattail.db', 'record_changes') == 'True':
 
    global ignore_role_changes
 
    ignore_role_changes = config.getboolean(
 
        'rattail.db', 'changes.ignore_roles', default=True)
 

	
 
    if config.getboolean('rattail.db', 'changes.record'):
 
        record_changes(edbob.Session)
 

	
 
    elif config.getboolean('rattail.db', 'record_changes'):
 
        warnings.warn("Config setting 'record_changes' in section [rattail.db] "
 
                      "is deprecated; please use 'changes.record' instead.",
 
                      DeprecationWarning)
 
        record_changes(edbob.Session)
0 comments (0 inline, 0 general)