hello. Some rambling on the ORM-layer.
We have our own self-awareness framework (e.g. active-record-like metadata-keeping - attributes, types, validation, ...), it's called StaticType as it does just that - structures defined through it are staticly-typed; no dynamic attributes, and no __dict__ at all. They form the model, and everything after that is derived from/around them - dialogs, db, etc. All is implemented with metaclasses / descriptors. So instead of reinventing the Obj-to-DB mapping wheel on some primitive level, we decided to use SQL Alchemy. Several problems arouse with this (from concrete to abstract): - SA expects my objects to have __dict__, and uses it directly to get/set attributes - SA expects to be able to add any extra attributes to my objects, be them system (e.g,. _sa_session_id) or not (foreign-key-columns) - SA uses privately-named __sa_attr_state and while haveing properly set _state avoids the whole need of it, even attempts to set it up in a manager_attribute.init_attr() - just to save some AttributeError later - SA pushes db-semantics onto the objects, effectively making them just __dict__s; any class X:pass works okay. I mean, the objects are seen as extension to the database schema, and not the other way around. Especialy with the persistency, where SA remembers history of changes, and on unsuccessful transaction, that is, rollback (), discards any values i have assigned to them and restores old values, whatever they are. i have invented a (slow!) solution/workaround for the first 3, but it would be better if SA has more consistency in handling the objects - e.g. need only ONE attribute and put any extra stuff into it, while using proper getattr/setattr for the plain attributes. For the last db-semantic stuff, i would like to be able to not have my objects with exactly this db-persistency semantic pushed on them. So if a object-saving transaction fails, okay, the object is still dirty, let me retry later. Imagine that the data in the object needs hours to be calculated. Eventualy, i would like to have my own concept of dirti'ness. Comparing things AND keeping history etc is not the best way sometimes. Otherwise, the objects connected to the SA would have to be just (smartly?) persistent copies of my own separate non-persistent objects. Which sort-of makes the whole thing smelly... Maybe if the dirtiness and related stuff can be separated from the mapper in an (optional) layer/protocol, replaceable by external class of same protocol, that would solve my problem. Of course, it may have some unknwon-yet consequences, similar to, in a push-vs-pull concepts, if there are two pushers attached against each other, both trying to make the other one do something he cannot. we will probably try do the above ourselves, copying data is not my piece of cake, as i want each object to exist in ONE only instance. so far all else is okay. keep up the good work! code-follows - for those who may have similar problems ================================ ##svd'2006 if 'AVOID having privately-named __sa_attr_state': from sqlalchemy.orm import mapperlib mapperlib.attribute_manager.init_attr = lambda me: None #DO NOT setup _sa_attr class dict_via_attr( object): '''this to avoid having __dict__ - SA uses __dict__ directly, for both normal and for additionaly mapped attributes, e.g. ab_id; use as __dict__ = property( dict_via_attr) ''' __slots__ = [ 'src' ] def __init__( me, src): me.src = src def has_key( me, k): try: me[k] except KeyError: return False return True def __getitem__( me,k): src = me.src try: return getattr( src._props, k) except AttributeError,e: try: d = src._my_sa_stuff except AttributeError: d = src._my_sa_stuff = dict() #raise KeyError, a.args return d[k] def __setitem__( me, k,v): src = me.src try: return setattr( src._props, k,v) except AttributeError,e: try: d = src._my_sa_stuff except AttributeError: d = src._my_sa_stuff = dict() return d.__setitem__( k,v) class Model4SA( Model): #Model is our base class __slots__ = [ '__weakref__', '_sa_session_id', '_sa_insert_order', '_instance_key', '_entity_name', '_my_state', '_my_sa_stuff', ] def _lazy_mystate( me): try: return me._my_state except AttributeError: m = me._my_state = {} return m _state = property( _lazy_mystate) __dict__ = property( dict_via_attr ) __doc__ = ''' SA uses obj.__dict__ directly - expects to add any stuff to it! NO __dict__ here - all is done to avoid it, as it shades the object and makes all the StaticType'ing meaningless. SA-mapper-related attributes are hence split into these categories: system: _state and others in the __slots__ above extra columns (foreign keys etc): go in _my_sa_stuff plain attributes: go in the object via get/set attr this exercise would be a lot easier if: - _state didn't use/make a privately-named __sa_attr_state but just plain name (just _sa_attr_state) (and the attribute_manager.init_attr() is redundant - one func-call is ALOT slower than AttributeError exception) - plain attributes didn't access directly obj.__dict__[k], but have proper get/setattr(obj,k) - extra columns and extra system attributes went all into the above _state, or anywhere but in ONE place. ''' #######.... subclass Model4SA instead of Model ... # #class B( Model4SA): # name = _static_type.Text() # next = _static_type.ForwardStruct('C') ........... --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---