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
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)
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):
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:
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)
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'
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::
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']
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__:
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:
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()
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()].
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.
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))
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
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):
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()
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'