]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- the "synonym" function is now directly usable with
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 15 Mar 2008 20:18:54 +0000 (20:18 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 15 Mar 2008 20:18:54 +0000 (20:18 +0000)
"declarative".  Pass in the decorated property using
the "instrument" keyword argument, e.g.:
somekey = synonym('_somekey', instrument=property(g, s))
- declared_synonym deprecated

CHANGES
doc/build/content/plugins.txt
lib/sqlalchemy/ext/declarative.py
lib/sqlalchemy/orm/__init__.py
lib/sqlalchemy/orm/mapper.py
lib/sqlalchemy/orm/properties.py
test/ext/declarative.py

diff --git a/CHANGES b/CHANGES
index 01f0546edab6e48cec13acb3c2344e1257085255..006849a420c293ed5c50d3708b72bd1c189c40a8 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -16,7 +16,13 @@ CHANGES
       from being used with inheritance
 
     - Session.execute can now find binds from metadata
-        
+
+- extensions
+    - the "synonym" function is now directly usable with 
+      "declarative".  Pass in the decorated property using 
+      the "instrument" keyword argument, e.g.:
+      somekey = synonym('_somekey', instrument=property(g, s))
+      
 0.4.4
 ------
 - sql
index ed3869c248241bf29cce566af4826bf69a730ddb..8c1d3a55bd26bb8a312ba9c4e544e65a9f0d13a2 100644 (file)
@@ -17,7 +17,7 @@ declarative moves these three types of configuration underneath the individual m
 in most cases:
 
     {python}
-    from sqlalchemy.ext.declarative import declarative_base, declared_synonym
+    from sqlalchemy.ext.declarative import declarative_base
     
     engine = create_engine('sqlite://')
     Base = declarative_base(engine)
@@ -81,8 +81,8 @@ using them:
         user_id = Column('user_id', Integer, ForeignKey('users.id'))
         user = relation(User, primaryjoin=user_id==User.id)
 
-Synonyms are one area where `declarative` needs to slightly change the usual SQLAlchemy configurational syntax. To define a getter/setter which
-proxies to an underlying attribute, use `declared_synonym`:
+Synonyms are one area where `declarative` needs to slightly change the usual SQLAlchemy configurational syntax. To define a
+getter/setter which proxies to an underlying attribute, use `synonym` with the `instruments` argument:
 
     {python}
     class MyClass(Base):
@@ -94,7 +94,7 @@ proxies to an underlying attribute, use `declared_synonym`:
             return self._some_attr
         def _set_attr(self, attr)
             self._some_attr = attr
-        attr = declared_synonym(property(_get_attr, _set_attr), '_attr')
+        attr = synonym('_attr', instruments=property(_get_attr, _set_attr))
         
 The above synonym is then usable as an instance attribute as well as a class-level expression construct:
 
index b1bd07fbf5fd794bb333cf2ef85d9982294cd902..4feb47456655385b03a77f93e0064bfd8bd83890 100644 (file)
@@ -6,7 +6,7 @@ declarative moves these three types of configuration underneath the
 individual mapped class.   Regular SQLAlchemy schema and ORM 
 constructs are used in most cases::
 
-    from sqlalchemy.ext.declarative import declarative_base, declared_synonym
+    from sqlalchemy.ext.declarative import declarative_base
     
     engine = create_engine('sqlite://')
     Base = declarative_base(engine)
@@ -73,7 +73,7 @@ using them::
 
 Synonyms are one area where ``declarative`` needs to slightly change the usual
 SQLAlchemy configurational syntax.  To define a getter/setter which proxies
-to an underlying attribute, use ``declared_synonym``::
+to an underlying attribute, use ``synonym`` with the ``instruments`` argument::
 
     class MyClass(Base):
         __tablename__ = 'sometable'
@@ -84,7 +84,7 @@ to an underlying attribute, use ``declared_synonym``::
             return self._some_attr
         def _set_attr(self, attr)
             self._some_attr = attr
-        attr = declared_synonym(property(_get_attr, _set_attr), '_attr')
+        attr = synonym('_attr', instruments=property(_get_attr, _set_attr))
         
 The above synonym is then usable as an instance attribute as well as a class-level
 expression construct::
@@ -146,6 +146,7 @@ from sqlalchemy.schema import Table, SchemaItem, Column, MetaData
 from sqlalchemy.orm import synonym as _orm_synonym, mapper
 from sqlalchemy.orm.interfaces import MapperProperty
 from sqlalchemy.orm.properties import PropertyLoader
+from sqlalchemy import util
 
 __all__ = ['declarative_base', 'declared_synonym']
 
@@ -158,13 +159,10 @@ class DeclarativeMeta(type):
         our_stuff = {}
         for k in dict_:
             value = dict_[k]
-            if not isinstance(value, (Column, MapperProperty, declared_synonym)):
+            if not isinstance(value, (Column, MapperProperty)):
                 continue
-            if isinstance(value, declared_synonym):
-                value._setup(cls, k, our_stuff)
-            else:
-                prop = _deferred_relation(cls, value)
-                our_stuff[k] = prop
+            prop = _deferred_relation(cls, value)
+            our_stuff[k] = prop
         
         table = None
         if '__table__' not in cls.__dict__:
@@ -195,8 +193,6 @@ class DeclarativeMeta(type):
                 cls.__mapper__.add_property(key, value)
             elif isinstance(value, MapperProperty):
                 cls.__mapper__.add_property(key, _deferred_relation(cls, value))
-            elif isinstance(value, declared_synonym):
-                value._setup(cls, key, None)
             else:
                 type.__setattr__(cls, key, value)
         else:
@@ -211,23 +207,11 @@ def _deferred_relation(cls, prop):
 
     return prop
 
-class declared_synonym(object):
-    def __init__(self, prop, name, mapperprop=None):
-        self.prop = prop
-        self.name = name
-        self.mapperprop = mapperprop
-        
-    def _setup(self, cls, key, init_dict):
-        prop = self.mapperprop or getattr(cls, self.name)
-        prop = _deferred_relation(cls, prop)
-        setattr(cls, key, self.prop)
-        if init_dict is not None:
-            init_dict[self.name] = prop
-            init_dict[key] = _orm_synonym(self.name)
-        else:
-            setattr(cls, self.name, prop)
-            setattr(cls, key, _orm_synonym(self.name))
-        
+def declared_synonym(prop, name):
+    """deprecated.  use synonym(name, instrument=prop)."""
+    
+    return _orm_synonym(name, instrument=prop)
+declared_synonym = util.deprecated(declared_synonym)
         
 def declarative_base(engine=None, metadata=None):
     lcl_metadata = metadata or MetaData()
index 46c81952f870908945b46142bc445c04c6b09474..d7b5580647a2b9dd97b76ed5667f7366ad5bf41d 100644 (file)
@@ -547,7 +547,7 @@ def mapper(class_, local_table=None, *args, **params):
 
     return Mapper(class_, local_table, *args, **params)
 
-def synonym(name, map_column=False, proxy=False):
+def synonym(name, map_column=False, instrument=None, proxy=False):
     """Set up `name` as a synonym to another mapped property.
 
     Used with the ``properties`` dictionary sent to  [sqlalchemy.orm#mapper()].
@@ -589,7 +589,7 @@ def synonym(name, map_column=False, proxy=False):
     is not already available.
     """
 
-    return SynonymProperty(name, map_column=map_column)
+    return SynonymProperty(name, map_column=map_column, instrument=instrument)
 
 def compile_mappers():
     """Compile all mappers that have been defined.
index 4a8e592ceed8e7e73ec5ecf9bde80f3d135f325a..36a6632554761408446cdd66e4d2c729890ac640 100644 (file)
@@ -653,9 +653,10 @@ class Mapper(object):
                 for col in col.proxy_set:
                     self._columntoproperty[col] = prop
         elif isinstance(prop, SynonymProperty) and setparent:
-            prop.instrument = getattr(self.class_, key, None)
-            if isinstance(prop.instrument, Mapper._CompileOnAttr):
-                prop.instrument = object.__getattribute__(prop.instrument, 'existing_prop')
+            if prop.instrument is None:
+                prop.instrument = getattr(self.class_, key, None)
+                if isinstance(prop.instrument, Mapper._CompileOnAttr):
+                    prop.instrument = object.__getattribute__(prop.instrument, 'existing_prop')
             if prop.map_column:
                 if not key in self.mapped_table.c:
                     raise exceptions.ArgumentError("Can't compile synonym '%s': no column on table '%s' named '%s'"  % (prop.name, self.mapped_table.description, key))
index 79c4ba63b0174ed6f30625c5e2ca8c141215db1d..1866693b4da4fe2b622e074dcdbd62444682248e 100644 (file)
@@ -150,10 +150,10 @@ class CompositeProperty(ColumnProperty):
                                  other.__composite_values__())])
 
 class SynonymProperty(MapperProperty):
-    def __init__(self, name, map_column=None):
+    def __init__(self, name, map_column=None, instrument=None):
         self.name = name
         self.map_column=map_column
-        self.instrument = None
+        self.instrument = instrument
 
     def setup(self, querycontext, **kwargs):
         pass
@@ -177,7 +177,6 @@ class SynonymProperty(MapperProperty):
                         return s
                     return getattr(obj, self.name)
             self.instrument = SynonymProp()
-
         sessionlib.register_attribute(class_, self.key, uselist=False, proxy_property=self.instrument, useobject=False, comparator=comparator)
 
     def merge(self, session, source, dest, _recursive):
index 66ceb718b381a91099214d51b7c4845c78c1714a..ef5fc87c6cba014b71c6d9d8b045cef504abaf26 100644 (file)
@@ -93,7 +93,7 @@ class DeclarativeTest(TestBase):
                 self._name = "SOMENAME " + name
             def _get_name(self):
                 return self._name
-            name = declared_synonym(property(_get_name, _set_name), '_name')
+            name = synonym('_name', instrument=property(_get_name, _set_name))
             
         Base.metadata.create_all()
         
@@ -104,7 +104,52 @@ class DeclarativeTest(TestBase):
         sess.flush()
         self.assertEquals(sess.query(User).filter(User.name=="SOMENAME someuser").one(), u1)
 
+    @testing.uses_deprecated('Call to deprecated function declared_synonym')
+    def test_decl_synonym_inline(self):
+        class User(Base, Fixture):
+            __tablename__ = 'users'
+
+            id = Column('id', Integer, primary_key=True)
+            _name = Column('name', String(50))
+            def _set_name(self, name):
+                self._name = "SOMENAME " + name
+            def _get_name(self):
+                return self._name
+            name = declared_synonym(property(_get_name, _set_name), '_name')
+
+        Base.metadata.create_all()
+
+        sess = create_session()
+        u1 = User(name='someuser')
+        assert u1.name == "SOMENAME someuser", u1.name
+        sess.save(u1)
+        sess.flush()
+        self.assertEquals(sess.query(User).filter(User.name=="SOMENAME someuser").one(), u1)
+
     def test_synonym_added(self):
+        class User(Base, Fixture):
+            __tablename__ = 'users'
+
+            id = Column('id', Integer, primary_key=True)
+            _name = Column('name', String(50))
+            def _set_name(self, name):
+                self._name = "SOMENAME " + name
+            def _get_name(self):
+                return self._name
+            name = property(_get_name, _set_name)
+        User.name = synonym('_name', instrument=User.name)
+
+        Base.metadata.create_all()
+
+        sess = create_session()
+        u1 = User(name='someuser')
+        assert u1.name == "SOMENAME someuser", u1.name
+        sess.save(u1)
+        sess.flush()
+        self.assertEquals(sess.query(User).filter(User.name=="SOMENAME someuser").one(), u1)
+
+    @testing.uses_deprecated('Call to deprecated function declared_synonym')
+    def test_decl_synonym_added(self):
         class User(Base, Fixture):
             __tablename__ = 'users'