| 1 | """ | 
|---|
| 2 | This is similar to the assignmapper extensions in SQLAclhemy 0.3 and 0.4 but | 
|---|
| 3 | with some compatibility fixes. It assumes that the session is a ScopedSession, | 
|---|
| 4 | and thus has the "mapper" method to attach contextual mappers to a class. It | 
|---|
| 5 | adds additional query and session methods to the class to support the | 
|---|
| 6 | SQLAlchemy 0.3 style of access. | 
|---|
| 7 |  | 
|---|
| 8 | The following Session methods, which normally accept an instance | 
|---|
| 9 | or list of instances, are available directly through the objects, e.g. | 
|---|
| 10 | "Session.flush( [instance] )" can be performed as "instance.flush()": | 
|---|
| 11 |  | 
|---|
| 12 | """ | 
|---|
| 13 |  | 
|---|
| 14 | __all__ = [ 'assign_mapper' ] | 
|---|
| 15 |  | 
|---|
| 16 | from sqlalchemy import util, exceptions | 
|---|
| 17 | import types | 
|---|
| 18 | from sqlalchemy.orm import Query | 
|---|
| 19 | from sqlalchemy.orm import mapper as sqla_mapper | 
|---|
| 20 |  | 
|---|
| 21 | def _monkeypatch_query_method( name, session, class_ ): | 
|---|
| 22 | def do(self, *args, **kwargs): | 
|---|
| 23 | return getattr( class_.query, name)(*args, **kwargs) | 
|---|
| 24 | try: | 
|---|
| 25 | do.__name__ = name | 
|---|
| 26 | except: | 
|---|
| 27 | pass | 
|---|
| 28 | if not hasattr(class_, name): | 
|---|
| 29 | setattr(class_, name, classmethod(do)) | 
|---|
| 30 | def session_mapper( scoped_session, class_, *args, **kwargs ): | 
|---|
| 31 | def mapper( cls, *arg, **kw ): | 
|---|
| 32 | validate = kw.pop( 'validate', False ) | 
|---|
| 33 | if cls.__init__ is object.__init__: | 
|---|
| 34 | def __init__( self, **kwargs ): | 
|---|
| 35 | for key, value in kwargs.items(): | 
|---|
| 36 | if validate: | 
|---|
| 37 | if not cls_mapper.has_property( key ): | 
|---|
| 38 | raise TypeError( "Invalid __init__ argument: '%s'" % key ) | 
|---|
| 39 | setattr( self, key, value ) | 
|---|
| 40 | cls.__init__ = __init__ | 
|---|
| 41 | cls.query = scoped_session.query_property() | 
|---|
| 42 | # FIXME: eliminate the need for the following monkey patch by fixing the single | 
|---|
| 43 | # query in ~/datatypes/metadata.py in the FileParameter.wrap() method | 
|---|
| 44 | _monkeypatch_query_method( 'get', scoped_session, cls ) | 
|---|
| 45 | return sqla_mapper( cls, *arg, **kw ) | 
|---|
| 46 | return mapper( class_, *args, **kwargs ) | 
|---|
| 47 | def assign_mapper( session, class_, *args, **kwargs ): | 
|---|
| 48 | m = class_.mapper = session_mapper( session, class_, *args, **kwargs ) | 
|---|
| 49 | return m | 
|---|