[sqlalchemy] Re: branch:user_defined_state questions
On Apr 30, 2008, at 8:50 AM, [EMAIL PROTECTED] wrote: - replacing __init__(...) - i see that some effort is taken to keep the original signature. But the result wont be debuggable IMO. cant it be some_init(*a,**kw) doing whatever( *a,**kw) and/or calling original_init(*a,**kw) ? whats inside is not changing as sequence/logic anyway... OR, maybe fix/hack with the co_filename and co_firstlineno code-attributes or whatever so inspect.getsource( damnedclass.__init__) works... are we talking about the __init__ placed on instances ? how is that not debuggable ? I know that pdb is forced to illustrate one line in the trace as being part of a string but thats not such a big deal. i have some obj.pre_save() hook-method that is called just before session.save_or_update( obj), to do last-point validations and/or setup of timestamp-like fields. There's an idea/ need to replace that with mapper_extension.before_insert() but i'm not sure if these are going to be equivalent flow-wise. To me, save() is much higher level thing than before_insert - nothing has happened yet, and an exception thrown in wanna-be save() isnt going to cancel anything big... while in before_insert() is going to force a rollback, no? i.e. undo stuff that IS already done to the db. Also pulling things into flush isnt possible in before_insert() - not that i'm doing such things but who knows who's gonna use that hook for what.. you should use a SessionExtension for this hook. It'll give you a pre- flush() which I think it what you're looking for. flushes do roll back still. Some DB's can't continue after various kinds of constraint violations occur (Postgres after a primary key violation comes to mind). Although using SAVEPOINTs, flushes can be made to be atomic within a larger transaction (and we're going to have great support for that). now, why i got here at all... in order to call the pre_save() i am duplicating the save() behaviour to setup a _state if an instance doesnt have one. do i really need that? looks like i may want to hook before session.save() calls the session._save_impl(), when the state is already there... which is only possible in the branch now. ok i'll do my own _state_setup() for backward compatibility the ORM ensures that instances always have a _state. I think the primary entry point on that is via the instrumented __init__() method as well as the on-load hooks. I dont know why you'd need to set up a _state even in 0.4, that's an internal detail which the ORM handles (unless you're blowing away SA's __init__ decorator, which would be bad). sql.visitors.ClauseVisitor: - seems the place/order of actual visitation has changed... before order was children then parents (post-walk, depth first), now it jumps straight onto parent (e.g. visit_binary) before any child (pre-walk ?). Isn't quite a time to fix this visiting pattern, allowing more flexibility? As i see, the iterate_depthfirst is what i need, and i hacked module-level iterate to point to that, but that isn't a good way - i need it temporarily. IMO the visitors.traverse() should have one more argument iterator_func, and that to be passed whatever the Visitor's .iterate is, instead of using hardcoded module-level iterate. I just added traverse_depthfirst() for you.In reality, I dont need iterate/traverse_depthfirst() at all and I was almost going to just remove them the other day, so maybe you should just maintain these on your end if you need a very specific traversal. As far as the callable, thats nice for a general use API but thats not really what visitors is right now - I dont need to have all of my ORM functions piecing together iterate + traversal functions since for my needs the order of iteration is never important. When I need to copy and modify the structure, I have cloned_traverse() and replacement_traverse() which have very specific traversal orders based on what they need to do. - those name[6:] things... mmh. there was a metaclass trick I was working on there but it ran into problems. so that approach there is temporary until something class- level can be worked out. hey, i start to notice some pattern ... where i use something sa-internal, the more quick/hackish/inflexible it has been done, the more (frequently) it changes - so i have many many versions of ways of using it. do u want some statistix which items got biggest number of versions so far ? (:-) heres an idea - dont write your application to sqlalchemy internals ! of course the more hacky ones are going to change more frequently since we're still figuring out the best way to do them (thats why they're...hacky !)I cant think of any code even in 0.5's progress that isnt subject to being massively changed yet again (for example, sync.py and dependency.py are very solid now, and aren't changing at all...but what if someday we reduce the
[sqlalchemy] Re: branch:user_defined_state questions
Michael Bayer wrote: On Apr 30, 2008, at 8:50 AM, [EMAIL PROTECTED] wrote: - replacing __init__(...) - i see that some effort is taken to keep the original signature. But the result wont be debuggable IMO. cant it be some_init(*a,**kw) doing whatever( *a,**kw) and/or calling original_init(*a,**kw) ? whats inside is not changing as sequence/logic anyway... OR, maybe fix/hack with the co_filename and co_firstlineno code-attributes or whatever so inspect.getsource( damnedclass.__init__) works... are we talking about the __init__ placed on instances ? how is that not debuggable ? I know that pdb is forced to illustrate one line in the trace as being part of a string but thats not such a big deal. Also, the __init__ decorator is optional in UDS/0.5. The class instrumentor will receive a 'install_member('__init__', sa's default genned function)' call and can do whatever it likes with that. The toolkit is in place for building and substituting your own non-exec'd __init__ that does the setup work SA wants done on init. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: branch:user_defined_state questions
On Apr 30, 2008, at 8:50 AM, [EMAIL PROTECTED] wrote: should have one more argument iterator_func, and that to be passed whatever the Visitor's .iterate is, instead of using hardcoded fine. r4607: def traverse_using(iterator, obj, visitors): visit the given expression structure using the given iterator of objects. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: branch:user_defined_state questions
On Wednesday 30 April 2008 18:25:25 Michael Bayer wrote: On Apr 30, 2008, at 8:50 AM, [EMAIL PROTECTED] wrote: should have one more argument iterator_func, and that to be passed whatever the Visitor's .iterate is, instead of using hardcoded fine. r4607: def traverse_using(iterator, obj, visitors): visit the given expression structure using the given iterator of objects. yeah, i how i get the ClauseVisitor to use that... The idea was for the ClauseVisitor's traverse to use ClauseVisitor's iterate (or _iterate), pointing by default to module's plain iterate(), so inheriting and replaceing _iterate with e.g. iterate_depth_first (or whatever fancy) would work, without a need to reinvent the traverse mechanism at all. unless u're fading out those classes for a reason or another? --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: branch:user_defined_state questions
On Apr 30, 2008, at 12:26 PM, [EMAIL PROTECTED] wrote: On Wednesday 30 April 2008 18:25:25 Michael Bayer wrote: On Apr 30, 2008, at 8:50 AM, [EMAIL PROTECTED] wrote: should have one more argument iterator_func, and that to be passed whatever the Visitor's .iterate is, instead of using hardcoded fine. r4607: def traverse_using(iterator, obj, visitors): visit the given expression structure using the given iterator of objects. yeah, i how i get the ClauseVisitor to use that... The idea was for the ClauseVisitor's traverse to use ClauseVisitor's iterate (or _iterate), pointing by default to module's plain iterate(), so inheriting and replaceing _iterate with e.g. iterate_depth_first (or whatever fancy) would work, without a need to reinvent the traverse mechanism at all. unless u're fading out those classes for a reason or another? no theyre hanging around. Just subclass ClauseVisitor for now. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: branch:user_defined_state questions
i have some obj.pre_save() hook-method that is called just before session.save_or_update( obj), to do last-point validations and/or setup of timestamp-like fields. There's an idea/ need to replace that with mapper_extension.before_insert() but i'm not sure if these are going to be equivalent flow-wise. To me, save() is much higher level thing than before_insert - nothing has happened yet, and an exception thrown in wanna-be save() isnt going to cancel anything big... while in before_insert() is going to force a rollback, no? i.e. undo stuff that IS already done to the db. Also pulling things into flush isnt possible in before_insert() - not that i'm doing such things but who knows who's gonna use that hook for what.. you should use a SessionExtension for this hook. It'll give you a pre- flush() which I think it what you're looking for. flushes do roll back still. Some DB's can't continue after various kinds of constraint violations occur (Postgres after a primary key violation comes to mind). Although using SAVEPOINTs, flushes can be made to be atomic within a larger transaction (and we're going to have great support for that). hmm i did look at SessionExtension but thats seems lower/later level than i need. but i'll think about it. now, why i got here at all... in order to call the pre_save() i am duplicating the save() behaviour to setup a _state if an instance doesnt have one. do i really need that? looks like i may want to hook before session.save() calls the session._save_impl(), when the state is already there... which is only possible in the branch now. ok i'll do my own _state_setup() for backward compatibility the ORM ensures that instances always have a _state. I think the primary entry point on that is via the instrumented __init__() method as well as the on-load hooks. I dont know why you'd need to set up a _state even in 0.4, that's an internal detail which the ORM handles (unless you're blowing away SA's __init__ decorator, which would be bad). ok then, u bet its not needed... for whatever reason it is there - i dont remember exactly - around v3463 /InstanceState first appearance... i'll take it out and see what breaks. hey, i start to notice some pattern ... where i use something sa-internal, the more quick/hackish/inflexible it has been done, the more (frequently) it changes - so i have many many versions of ways of using it. do u want some statistix which items got biggest number of versions so far ? (:-) heres an idea - dont write your application to sqlalchemy internals ! of course the more hacky ones are going to change more frequently since we're still figuring out the best way to do them (thats why they're...hacky !)I cant think of any code even in 0.5's progress that isnt subject to being massively changed yet again (for example, sync.py and dependency.py are very solid now, and aren't changing at all...but what if someday we reduce the overall complexity of the flush process such that they aren't needed ? its possible) heh, dont take me wrong. it's not for the first time u know - i'm not complaining. My idea is that this statistical way maybe we can figure out possibly shaky pieces not yet under proper interface... e.g. few examples of my pokings so far are: polymorphism, whole attribute-access story, mapper's selecttable, get_equivalent_columns, sql- expressions, operators and visitors, property_get_join, properties access and iteration, collection.append, ... As of SA internals... they represent quite a powerful language, much more juicy than the official API, that's why i'm using it... i just have to. i guess (or i hope?) sooner or later most of what i have found usable will become an interface in a way or another. ah nevermind. btw the concrete-polymorphism errors come at v4371, and branch has them too. Next thing i'll be looking at. is the branch going to be merged any soon or not really? its going to merge extremely soon. ok.. the error is about B inheriting A, concrete, inserting instance- of B, then doing session.query(A), and that yields nothing. Note the polymunion contents... if i add A there, then error goes away (???). i do remember some similar case maybe half an year ago... test attached. ciao svilen --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~--- _test_ABC_all.py Description: application/python
[sqlalchemy] Re: branch:user_defined_state questions
fine. r4607: def traverse_using(iterator, obj, visitors): visit the given expression structure using the given iterator of objects. yeah, i how i get the ClauseVisitor to use that... The idea was for the ClauseVisitor's traverse to use ClauseVisitor's iterate (or _iterate), pointing by default to module's plain iterate(), so inheriting and replaceing _iterate with e.g. iterate_depth_first (or whatever fancy) would work, without a need to reinvent the traverse mechanism at all. unless u're fading out those classes for a reason or another? no theyre hanging around. Just subclass ClauseVisitor for now. ok, i need the traverse_using(), the iterate_depth_first (which i can do myself as u said so its not really needed), and the pre-traverse name[6:] filtering: visitors = dict( (name[6:], getattr(self, name)) for name in dir(self) if name.startswith('visit_') ) u have this filtering copied twice, i guess it has to be in one place. so the actual traverse-call has to be one more method.. to be easy replaceable. that should make a good clean interface. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---