[sqlalchemy] Re: branch:user_defined_state questions

2008-04-30 Thread Michael Bayer


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

2008-04-30 Thread jason kirtland

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

2008-04-30 Thread Michael Bayer


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

2008-04-30 Thread az

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

2008-04-30 Thread Michael Bayer


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

2008-04-30 Thread az
  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

2008-04-30 Thread az

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