[2] | 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 |
---|