Commits

Vladimir Mihailenco  committed 25948cb

Fix transaction handling; fix mapping foreign keys

  • Participants
  • Parent commits 134e372

Comments (0)

Files changed (3)

File djsqlalchemy/alchemy.py

 
 def get_engine():
     if not getattr(mem, 'engine', None):
+        # we have to use autocommit=True, because SQLAlchemy
+        # is not aware of Django transactions
         mem.engine = create_engine(get_connection_string(),
-                                   pool=DjangoPool(creator=None))
+                                   pool=DjangoPool(creator=None),
+                                   execution_options=dict(autocommit=True))
     return mem.engine
 
 

File djsqlalchemy/mapper.py

+import logging
+
 from django.db.models import ForeignKey
 
 from djsqlalchemy.alchemy import get_engine
 
 def map_related(obj, values, prefix=''):
     # special case for master obj
-    local_prefix = prefix or (obj._meta.db_table + '_')
+    local_prefix = prefix or obj._meta.db_table
 
     fks = []
     for field in obj._meta.local_fields:
         if isinstance(field, ForeignKey):
             fks.append(field)
+
+            label = local_prefix + '_' + field.name + '_' + field.rel.field_name
+            attr = field.name + '_' + field.rel.field_name
+
         else:
-            label = local_prefix + field.name
-            if label in values:
-                setattr(obj, field.name, values[label])
-                del values[label]
+            label = local_prefix + '_' + field.name
+            attr = field.name
+
+        if label in values:
+            setattr(obj, attr, values[label])
+            del values[label]
 
     if obj.pk:
         for fk in fks:
             rel_obj = fk.rel.to()
-            map_related(rel_obj, values, prefix=prefix + fk.name + '_')
+            map_related(rel_obj, values, prefix=prefix + fk.name)
             if rel_obj.pk:
                 cache_name = '_%s_cache' % fk.name
                 setattr(obj, cache_name, rel_obj)

File djsqlalchemy/utils.py

-class _Missing(object):
-
-    def __repr__(self):
-        return 'no value'
-
-    def __reduce__(self):
-        return '_missing'
-
-_missing = _Missing()
-
-
 class cached_property(object):
-    """A decorator that converts a function into a lazy property. The
-function wrapped is called the first time to retrieve the result
-and then that calculated result is used the next time you access
-the value::
-
-class Foo(object):
-
-@cached_property
-def foo(self):
-# calculate something important here
-return 42
-
-The class has to have a `__dict__` in order for this property to
-work.
-
-.. versionchanged:: 0.6
-the `writeable` attribute and parameter was deprecated. If a
-cached property is writeable or not has to be documented now.
-For performance reasons the implementation does not honor the
-writeable setting and will always make the property writeable.
-"""
-
-    # implementation detail: this property is implemented as non-data
-    # descriptor. non-data descriptors are only invoked if there is
-    # no entry with the same name in the instance's __dict__.
-    # this allows us to completely get rid of the access function call
-    # overhead. If one choses to invoke __get__ by hand the property
-    # will still work as expected because the lookup logic is replicated
-    # in __get__ for manual invocation.
-
-    def __init__(self, func, name=None, doc=None, writeable=False):
-        if writeable:
-            from warnings import warn
-            warn(DeprecationWarning('the writeable argument to the '
-                                    'cached property is a noop since 0.6 '
-                                    'because the property is writeable '
-                                    'by default for performance reasons'))
-
-        self.__name__ = name or func.__name__
-        self.__module__ = func.__module__
-        self.__doc__ = doc or func.__doc__
+    def __init__(self, func):
         self.func = func
 
     def __get__(self, obj, type=None):
         if obj is None:
             return self
-        value = obj.__dict__.get(self.__name__, _missing)
-        if value is _missing:
-            value = self.func(obj)
-            obj.__dict__[self.__name__] = value
+
+        obj.__dict__[self.func.__name__] = value = self.func(obj)
         return value