1
2
3
4 """
5 SQLAlchemy adapter module.
6
7 @see: U{SQLAlchemy homepage (external)<http://www.sqlalchemy.org>}
8
9 @since: 0.4
10 """
11
12 from sqlalchemy import orm, __version__
13
14 try:
15 from sqlalchemy.orm import class_mapper
16 except ImportError:
17 from sqlalchemy.orm.util import class_mapper
18
19 import pyamf
20
21 UnmappedInstanceError = None
22
23 try:
24 class_mapper(dict)
25 except Exception, e:
26 UnmappedInstanceError = e.__class__
27
28
30 KEY_ATTR = 'sa_key'
31 LAZY_ATTR = 'sa_lazy'
32 EXCLUDED_ATTRS = [
33 '_entity_name', '_instance_key', '_sa_adapter', '_sa_appender',
34 '_sa_class_manager', '_sa_initiator', '_sa_instance_state',
35 '_sa_instrumented', '_sa_iterator', '_sa_remover', '_sa_session_id',
36 '_state'
37 ]
38
39 STATE_ATTR = '_sa_instance_state'
40
41 if __version__.startswith('0.4'):
42 STATE_ATTR = '_state'
43
45 self.mapper = class_mapper(self.klass)
46 self.exclude_attrs.update(self.EXCLUDED_ATTRS)
47
48 self.properties = []
49
50 for prop in self.mapper.iterate_properties:
51 self.properties.append(prop.key)
52
53 self.encodable_properties.update(self.properties)
54 self.decodable_properties.update(self.properties)
55 self.static_attrs.update(self.properties)
56
58 """
59 Returns a C{tuple} containing a dict of static and dynamic attributes
60 for C{obj}.
61 """
62 sa, da = pyamf.ClassAlias.getEncodableAttributes(self, obj, **kwargs)
63
64 if not da:
65 da = {}
66
67 lazy_attrs = []
68
69
70
71 da[self.KEY_ATTR] = self.mapper.primary_key_from_instance(obj)
72
73 for attr in self.properties:
74 if attr not in obj.__dict__:
75 lazy_attrs.append(attr)
76
77 da[self.LAZY_ATTR] = lazy_attrs
78
79 return sa, da
80
82 """
83 """
84 attrs = pyamf.ClassAlias.getDecodableAttributes(self, obj, attrs, **kwargs)
85
86
87
88
89
90
91
92
93
94
95 if self.LAZY_ATTR in attrs:
96 obj_state = None
97
98 if hasattr(orm.attributes, 'instance_state'):
99 obj_state = orm.attributes.instance_state(obj)
100
101 for lazy_attr in attrs[self.LAZY_ATTR]:
102 if lazy_attr in obj.__dict__:
103
104
105 del obj.__dict__[lazy_attr]
106
107
108
109
110
111
112
113 if obj_state is not None:
114 if lazy_attr in obj_state.committed_state:
115 del obj_state.committed_state[lazy_attr]
116 if lazy_attr in obj_state.dict:
117 del obj_state.dict[lazy_attr]
118
119 if lazy_attr in attrs:
120 del attrs[lazy_attr]
121
122 del attrs[self.LAZY_ATTR]
123
124 if self.KEY_ATTR in attrs:
125 del attrs[self.KEY_ATTR]
126
127 return attrs
128
129
131 """
132 @rtype: C{bool}
133 """
134 if not isinstance(klass, type):
135 klass = type(klass)
136
137 try:
138 class_mapper(klass)
139 except UnmappedInstanceError:
140 return False
141
142 return True
143
144 pyamf.register_alias_type(SaMappedClassAlias, is_class_sa_mapped)
145