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
-~----------~----~----~----~------~----~------~--~---

Reply via email to