Re: [sqlalchemy] ORM: walk() related objects

2015-09-15 Thread Pavel S
Final version:

def walk_related(obj, enableDuplicates=False, level=-1, memo=None):
memo = memo or set()

insp = inspect(obj)

for relobj in insp.mapper.cascade_iterator('delete', insp):
if enableDuplicates or relobj[0] not in memo:
memo.add(relobj[0])

yield level, relobj[0]

relatedObjects = walk_related(relobj[0],
enableDuplicates=enableDuplicates, level=level + 1, memo=
memo)

for walked_relobj in relatedObjects:
yield walked_relobj



Dne pondělí 14. září 2015 11:57:05 UTC+2 Pavel S napsal(a):
>
> Hi,
>
> I just realized that I need your first solution, since I need to get only 
> those objects that would cascade in case of deletion. 
>
> But thanks anyhow...
>
> P
>
> Dne čtvrtek 10. září 2015 15:35:39 UTC+2 Michael Bayer napsal(a):
>>
>>
>>
>> On 9/10/15 8:48 AM, Pavel S wrote:
>>
>> Let's say, I have declarative classes A, B, C, D.
>>
>> A is the parent
>> B has FK to A
>> C has FK to B,
>> D has FK to C etc...
>>
>> I'd like to implement *generic method* walk(obj) which will recursively 
>> yield dependent/related objects of obj (which is instance of A).
>>
>> I know that there is introspection interface inspect(), however I'm 
>> don't really understand how to use it properly in my use case.
>>
>> Shall I do inspect(obj) or rather inspect(obj.__class__) and then 
>> somehow apply inspection to obj?
>>
>> Are there an examples and best practices?
>>
>> right now you can kind of get this effect using cascade_iterator: 
>> http://docs.sqlalchemy.org/en/rel_1_0/orm/mapping_api.html?highlight=cascade_iterator#sqlalchemy.orm.mapper.Mapper.cascade_iterator
>>
>> the limitation is that right now its based on relationship cascade 
>> settings, as that's what it was intended for, so you'd probably want to use 
>> "save-update":
>>
>> insp = inspect(my_object)
>> for obj in insp.mapper.cascade_iterator("save-update", insp):
>># ...
>>
>> to implement your own system, the graph of objects is strictly based on 
>> relationship.   so walk() is pretty simple:
>>
>> def walk(obj):
>> yield obj
>> insp = inspect(obj)
>> for relationship in insp.mapper.relationships:
>> related = getattr(obj, relationship.key)
>> if relationship.uselist:
>> for collection_member in related:
>> for walk_related in walk(collection_member):
>> yield walk_related
>> elif related is not None:
>> for walk_related in walk(related):
>> yield walk_related
>>
>>
>>
>>
>>
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "sqlalchemy" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to sqlalchemy+...@googlegroups.com.
>> To post to this group, send email to sqlal...@googlegroups.com.
>> Visit this group at http://groups.google.com/group/sqlalchemy.
>> For more options, visit https://groups.google.com/d/optout.
>>
>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] ORM: walk() related objects

2015-09-14 Thread Pavel S
Hi,

I just realized that I need your first solution, since I need to get only 
those objects that would cascade in case of deletion. 

But thanks anyhow...

P

Dne čtvrtek 10. září 2015 15:35:39 UTC+2 Michael Bayer napsal(a):
>
>
>
> On 9/10/15 8:48 AM, Pavel S wrote:
>
> Let's say, I have declarative classes A, B, C, D.
>
> A is the parent
> B has FK to A
> C has FK to B,
> D has FK to C etc...
>
> I'd like to implement *generic method* walk(obj) which will recursively 
> yield dependent/related objects of obj (which is instance of A).
>
> I know that there is introspection interface inspect(), however I'm don't 
> really understand how to use it properly in my use case.
>
> Shall I do inspect(obj) or rather inspect(obj.__class__) and then somehow 
> apply inspection to obj?
>
> Are there an examples and best practices?
>
> right now you can kind of get this effect using cascade_iterator: 
> http://docs.sqlalchemy.org/en/rel_1_0/orm/mapping_api.html?highlight=cascade_iterator#sqlalchemy.orm.mapper.Mapper.cascade_iterator
>
> the limitation is that right now its based on relationship cascade 
> settings, as that's what it was intended for, so you'd probably want to use 
> "save-update":
>
> insp = inspect(my_object)
> for obj in insp.mapper.cascade_iterator("save-update", insp):
># ...
>
> to implement your own system, the graph of objects is strictly based on 
> relationship.   so walk() is pretty simple:
>
> def walk(obj):
> yield obj
> insp = inspect(obj)
> for relationship in insp.mapper.relationships:
> related = getattr(obj, relationship.key)
> if relationship.uselist:
> for collection_member in related:
> for walk_related in walk(collection_member):
> yield walk_related
> elif related is not None:
> for walk_related in walk(related):
> yield walk_related
>
>
>
>
>
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sqlalchemy+...@googlegroups.com .
> To post to this group, send email to sqlal...@googlegroups.com 
> .
> Visit this group at http://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] ORM: walk() related objects

2015-09-10 Thread Mike Bayer



On 9/10/15 8:48 AM, Pavel S wrote:

Let's say, I have declarative classes A, B, C, D.

A is the parent
B has FK to A
C has FK to B,
D has FK to C etc...

I'd like to implement _generic method_ walk(obj) which will 
recursively yield dependent/related objects of obj (which is instance 
of A).


I know that there is introspection interface inspect(), however I'm 
don't really understand how to use it properly in my use case.


Shall I do inspect(obj) or rather inspect(obj.__class__) and then 
somehow apply inspection to obj?


Are there an examples and best practices?
right now you can kind of get this effect using cascade_iterator: 
http://docs.sqlalchemy.org/en/rel_1_0/orm/mapping_api.html?highlight=cascade_iterator#sqlalchemy.orm.mapper.Mapper.cascade_iterator


the limitation is that right now its based on relationship cascade 
settings, as that's what it was intended for, so you'd probably want to 
use "save-update":


insp = inspect(my_object)
for obj in insp.mapper.cascade_iterator("save-update", insp):
   # ...

to implement your own system, the graph of objects is strictly based on 
relationship.   so walk() is pretty simple:


def walk(obj):
yield obj
insp = inspect(obj)
for relationship in insp.mapper.relationships:
related = getattr(obj, relationship.key)
if relationship.uselist:
for collection_member in related:
for walk_related in walk(collection_member):
yield walk_related
elif related is not None:
for walk_related in walk(related):
yield walk_related







--
You received this message because you are subscribed to the Google 
Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send 
an email to sqlalchemy+unsubscr...@googlegroups.com 
.
To post to this group, send email to sqlalchemy@googlegroups.com 
.

Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


--
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] ORM: walk() related objects

2015-09-10 Thread Pavel S
Hi Michael, this is amazing, thanks!!!


On Thursday, September 10, 2015 at 3:35:39 PM UTC+2, Michael Bayer wrote:
>
>
>
> On 9/10/15 8:48 AM, Pavel S wrote:
>
> Let's say, I have declarative classes A, B, C, D.
>
> A is the parent
> B has FK to A
> C has FK to B,
> D has FK to C etc...
>
> I'd like to implement *generic method* walk(obj) which will recursively 
> yield dependent/related objects of obj (which is instance of A).
>
> I know that there is introspection interface inspect(), however I'm don't 
> really understand how to use it properly in my use case.
>
> Shall I do inspect(obj) or rather inspect(obj.__class__) and then somehow 
> apply inspection to obj?
>
> Are there an examples and best practices?
>
> right now you can kind of get this effect using cascade_iterator: 
> http://docs.sqlalchemy.org/en/rel_1_0/orm/mapping_api.html?highlight=cascade_iterator#sqlalchemy.orm.mapper.Mapper.cascade_iterator
>
> the limitation is that right now its based on relationship cascade 
> settings, as that's what it was intended for, so you'd probably want to use 
> "save-update":
>
> insp = inspect(my_object)
> for obj in insp.mapper.cascade_iterator("save-update", insp):
># ...
>
> to implement your own system, the graph of objects is strictly based on 
> relationship.   so walk() is pretty simple:
>
> def walk(obj):
> yield obj
> insp = inspect(obj)
> for relationship in insp.mapper.relationships:
> related = getattr(obj, relationship.key)
> if relationship.uselist:
> for collection_member in related:
> for walk_related in walk(collection_member):
> yield walk_related
> elif related is not None:
> for walk_related in walk(related):
> yield walk_related
>
>
>
>
>
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sqlalchemy+...@googlegroups.com .
> To post to this group, send email to sqlal...@googlegroups.com 
> .
> Visit this group at http://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] ORM: walk() related objects

2015-09-10 Thread Pavel S
Let's say, I have declarative classes A, B, C, D.

A is the parent
B has FK to A
C has FK to B,
D has FK to C etc...

I'd like to implement *generic method* walk(obj) which will recursively 
yield dependent/related objects of obj (which is instance of A).

I know that there is introspection interface inspect(), however I'm don't 
really understand how to use it properly in my use case.

Shall I do inspect(obj) or rather inspect(obj.__class__) and then somehow 
apply inspection to obj?

Are there an examples and best practices?

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] ORM: walk() related objects

2015-09-10 Thread Ladislav Lenart
On 10.9.2015 16:30, Mike Bayer wrote:
> On 9/10/15 10:26 AM, Mike Bayer wrote:
>>
>>
>> On 9/10/15 10:13 AM, Ladislav Lenart wrote:
>>> Hello.
>>>
>>> Just a really, really tiny and pedantic correction... The stack 
>>> variable in the
>>> code is in fact a queue. This could potentially surprise some users / 
>>> readers.
>>>
>>> To fix, please do one of the following:
>>> * Rename stack local var to queue.
>>> * Use stack.pop() to pop the last element from the stack.
>>
>> there really should be some other name, because all the time, I have 
>> routines like this where even dynamically within the routine, the 
>> pop(0) is a pop() or vice-versa, because we'd like the iteration to 
>> work one way or another.  Changing pop(0) to pop() here means we are 
>> doing depth-first instead of breadth-first. So.  Some word that means 
>> "collection of things to operate upon"? I've seen "work" used.
>> "buffer" ?  eh.
>>
> 
> renamed to "deque".

Well, for me the name 'stack' automatically means depth-first whereas the name
'queue' means breadth-first. And when the name and the code do not match, I am
not sure what is the original intent. However, deque (or maybe dequeue?) is a
fine name for me.

BTW I've noticed that you use the term 'seen' for the set of already visited
objects. Perhaps you will like the name 'visit' (or 'to_visit' or
'not_visited')? At least that's what I use when I implement a visitor / iterator
pattern.

HTH,

Ladislav Lenart


>>> HTH,
>>>
>>> Ladislav Lenart
>>>
>>>
>>> On 10.9.2015 15:48, Mike Bayer wrote:

 On 9/10/15 9:35 AM, Mike Bayer wrote:
>
> On 9/10/15 8:48 AM, Pavel S wrote:
>> Let's say, I have declarative classes A, B, C, D.
>>
>> A is the parent
>> B has FK to A
>> C has FK to B,
>> D has FK to C etc...
>>
>> I'd like to implement _generic method_ walk(obj) which will 
>> recursively yield
>> dependent/related objects of obj (which is instance of A).
>>
>> I know that there is introspection interface inspect(), however 
>> I'm don't
>> really understand how to use it properly in my use case.
>>
>> Shall I do inspect(obj) or rather inspect(obj.__class__) and then 
>> somehow
>> apply inspection to obj?
>>
>> Are there an examples and best practices?
> right now you can kind of get this effect using cascade_iterator:
> http://docs.sqlalchemy.org/en/rel_1_0/orm/mapping_api.html?highlight=cascade_iterator#sqlalchemy.orm.mapper.Mapper.cascade_iterator
>  
>
>
> the limitation is that right now its based on relationship cascade 
> settings,
> as that's what it was intended for, so you'd probably want to use 
> "save-update":
>
> insp = inspect(my_object)
> for obj in insp.mapper.cascade_iterator("save-update", insp):
> # ...
>
> to implement your own system, the graph of objects is strictly 
> based on
> relationship.   so walk() is pretty simple:
>
> def walk(obj):
>  yield obj
>  insp = inspect(obj)
>  for relationship in insp.mapper.relationships:
>  related = getattr(obj, relationship.key)
>  if relationship.uselist:
>  for collection_member in related:
>  for walk_related in walk(collection_member):
>  yield walk_related
>  elif related is not None:
>  for walk_related in walk(related):
>  yield walk_related
 here's one im putting in the FAQ for now, which solves recursion 
 depth as well
 as cycles:

  def walk(obj):
  stack = [obj]

  seen = set()

  while stack:
  obj = stack.pop(0)
  if obj in seen:
  continue
  else:
  seen.add(obj)
  yield obj
  insp = inspect(obj)
  for relationship in insp.mapper.relationships:
  related = getattr(obj, relationship.key)
  if relationship.uselist:
  stack.extend(related)
  elif related is not None:
  stack.append(related)




>
>
>
>
>
>> -- 
>> You received this message because you are subscribed to the Google 
>> Groups
>> "sqlalchemy" group.
>> To unsubscribe from this group and stop receiving emails from it, 
>> send an
>> email to sqlalchemy+unsubscr...@googlegroups.com
>> .
>> To post to this group, send email to sqlalchemy@googlegroups.com
>> .
>> Visit this group at http://groups.google.com/group/sqlalchemy.
>> For more options, visit https://groups.google.com/d/optout.
> -- 
> You received this message because you are 

Re: [sqlalchemy] ORM: walk() related objects

2015-09-10 Thread Mike Bayer



On 9/10/15 9:35 AM, Mike Bayer wrote:



On 9/10/15 8:48 AM, Pavel S wrote:

Let's say, I have declarative classes A, B, C, D.

A is the parent
B has FK to A
C has FK to B,
D has FK to C etc...

I'd like to implement _generic method_ walk(obj) which will 
recursively yield dependent/related objects of obj (which is instance 
of A).


I know that there is introspection interface inspect(), however I'm 
don't really understand how to use it properly in my use case.


Shall I do inspect(obj) or rather inspect(obj.__class__) and then 
somehow apply inspection to obj?


Are there an examples and best practices?
right now you can kind of get this effect using cascade_iterator: 
http://docs.sqlalchemy.org/en/rel_1_0/orm/mapping_api.html?highlight=cascade_iterator#sqlalchemy.orm.mapper.Mapper.cascade_iterator


the limitation is that right now its based on relationship cascade 
settings, as that's what it was intended for, so you'd probably want 
to use "save-update":


insp = inspect(my_object)
for obj in insp.mapper.cascade_iterator("save-update", insp):
   # ...

to implement your own system, the graph of objects is strictly based 
on relationship.   so walk() is pretty simple:


def walk(obj):
yield obj
insp = inspect(obj)
for relationship in insp.mapper.relationships:
related = getattr(obj, relationship.key)
if relationship.uselist:
for collection_member in related:
for walk_related in walk(collection_member):
yield walk_related
elif related is not None:
for walk_related in walk(related):
yield walk_related


here's one im putting in the FAQ for now, which solves recursion depth 
as well as cycles:


def walk(obj):
stack = [obj]

seen = set()

while stack:
obj = stack.pop(0)
if obj in seen:
continue
else:
seen.add(obj)
yield obj
insp = inspect(obj)
for relationship in insp.mapper.relationships:
related = getattr(obj, relationship.key)
if relationship.uselist:
stack.extend(related)
elif related is not None:
stack.append(related)












--
You received this message because you are subscribed to the Google 
Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, 
send an email to sqlalchemy+unsubscr...@googlegroups.com 
.
To post to this group, send email to sqlalchemy@googlegroups.com 
.

Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


--
You received this message because you are subscribed to the Google 
Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send 
an email to sqlalchemy+unsubscr...@googlegroups.com 
.
To post to this group, send email to sqlalchemy@googlegroups.com 
.

Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


--
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] ORM: walk() related objects

2015-09-10 Thread Mike Bayer



On 9/10/15 10:26 AM, Mike Bayer wrote:



On 9/10/15 10:13 AM, Ladislav Lenart wrote:

Hello.

Just a really, really tiny and pedantic correction... The stack 
variable in the
code is in fact a queue. This could potentially surprise some users / 
readers.


To fix, please do one of the following:
* Rename stack local var to queue.
* Use stack.pop() to pop the last element from the stack.


there really should be some other name, because all the time, I have 
routines like this where even dynamically within the routine, the 
pop(0) is a pop() or vice-versa, because we'd like the iteration to 
work one way or another.  Changing pop(0) to pop() here means we are 
doing depth-first instead of breadth-first. So.  Some word that means 
"collection of things to operate upon"? I've seen "work" used.
"buffer" ?  eh.




renamed to "deque".




HTH,

Ladislav Lenart


On 10.9.2015 15:48, Mike Bayer wrote:


On 9/10/15 9:35 AM, Mike Bayer wrote:


On 9/10/15 8:48 AM, Pavel S wrote:

Let's say, I have declarative classes A, B, C, D.

A is the parent
B has FK to A
C has FK to B,
D has FK to C etc...

I'd like to implement _generic method_ walk(obj) which will 
recursively yield

dependent/related objects of obj (which is instance of A).

I know that there is introspection interface inspect(), however 
I'm don't

really understand how to use it properly in my use case.

Shall I do inspect(obj) or rather inspect(obj.__class__) and then 
somehow

apply inspection to obj?

Are there an examples and best practices?

right now you can kind of get this effect using cascade_iterator:
http://docs.sqlalchemy.org/en/rel_1_0/orm/mapping_api.html?highlight=cascade_iterator#sqlalchemy.orm.mapper.Mapper.cascade_iterator 



the limitation is that right now its based on relationship cascade 
settings,
as that's what it was intended for, so you'd probably want to use 
"save-update":


insp = inspect(my_object)
for obj in insp.mapper.cascade_iterator("save-update", insp):
# ...

to implement your own system, the graph of objects is strictly 
based on

relationship.   so walk() is pretty simple:

def walk(obj):
 yield obj
 insp = inspect(obj)
 for relationship in insp.mapper.relationships:
 related = getattr(obj, relationship.key)
 if relationship.uselist:
 for collection_member in related:
 for walk_related in walk(collection_member):
 yield walk_related
 elif related is not None:
 for walk_related in walk(related):
 yield walk_related
here's one im putting in the FAQ for now, which solves recursion 
depth as well

as cycles:

 def walk(obj):
 stack = [obj]

 seen = set()

 while stack:
 obj = stack.pop(0)
 if obj in seen:
 continue
 else:
 seen.add(obj)
 yield obj
 insp = inspect(obj)
 for relationship in insp.mapper.relationships:
 related = getattr(obj, relationship.key)
 if relationship.uselist:
 stack.extend(related)
 elif related is not None:
 stack.append(related)











--
You received this message because you are subscribed to the Google 
Groups

"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, 
send an

email to sqlalchemy+unsubscr...@googlegroups.com
.
To post to this group, send email to sqlalchemy@googlegroups.com
.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google 
Groups

"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, 
send an

email to sqlalchemy+unsubscr...@googlegroups.com
.
To post to this group, send email to sqlalchemy@googlegroups.com
.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google 
Groups

"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, 
send an email

to sqlalchemy+unsubscr...@googlegroups.com
.
To post to this group, send email to sqlalchemy@googlegroups.com
.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.






--
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this 

Re: [sqlalchemy] ORM: walk() related objects

2015-09-10 Thread Ladislav Lenart
Hello.

Just a really, really tiny and pedantic correction... The stack variable in the
code is in fact a queue. This could potentially surprise some users / readers.

To fix, please do one of the following:
* Rename stack local var to queue.
* Use stack.pop() to pop the last element from the stack.

HTH,

Ladislav Lenart


On 10.9.2015 15:48, Mike Bayer wrote:
> 
> 
> On 9/10/15 9:35 AM, Mike Bayer wrote:
>>
>>
>> On 9/10/15 8:48 AM, Pavel S wrote:
>>> Let's say, I have declarative classes A, B, C, D.
>>>
>>> A is the parent
>>> B has FK to A
>>> C has FK to B,
>>> D has FK to C etc...
>>>
>>> I'd like to implement _generic method_ walk(obj) which will recursively 
>>> yield
>>> dependent/related objects of obj (which is instance of A).
>>>
>>> I know that there is introspection interface inspect(), however I'm don't
>>> really understand how to use it properly in my use case.
>>>
>>> Shall I do inspect(obj) or rather inspect(obj.__class__) and then somehow
>>> apply inspection to obj?
>>>
>>> Are there an examples and best practices?
>> right now you can kind of get this effect using cascade_iterator:
>> http://docs.sqlalchemy.org/en/rel_1_0/orm/mapping_api.html?highlight=cascade_iterator#sqlalchemy.orm.mapper.Mapper.cascade_iterator
>>
>> the limitation is that right now its based on relationship cascade settings,
>> as that's what it was intended for, so you'd probably want to use 
>> "save-update":
>>
>> insp = inspect(my_object)
>> for obj in insp.mapper.cascade_iterator("save-update", insp):
>># ...
>>
>> to implement your own system, the graph of objects is strictly based on
>> relationship.   so walk() is pretty simple:
>>
>> def walk(obj):
>> yield obj
>> insp = inspect(obj)
>> for relationship in insp.mapper.relationships:
>> related = getattr(obj, relationship.key)
>> if relationship.uselist:
>> for collection_member in related:
>> for walk_related in walk(collection_member):
>> yield walk_related
>> elif related is not None:
>> for walk_related in walk(related):
>> yield walk_related
> 
> here's one im putting in the FAQ for now, which solves recursion depth as well
> as cycles:
> 
> def walk(obj):
> stack = [obj]
> 
> seen = set()
> 
> while stack:
> obj = stack.pop(0)
> if obj in seen:
> continue
> else:
> seen.add(obj)
> yield obj
> insp = inspect(obj)
> for relationship in insp.mapper.relationships:
> related = getattr(obj, relationship.key)
> if relationship.uselist:
> stack.extend(related)
> elif related is not None:
> stack.append(related)
> 
> 
> 
> 
>>
>>
>>
>>
>>
>>
>>> -- 
>>> You received this message because you are subscribed to the Google Groups
>>> "sqlalchemy" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an
>>> email to sqlalchemy+unsubscr...@googlegroups.com
>>> .
>>> To post to this group, send email to sqlalchemy@googlegroups.com
>>> .
>>> Visit this group at http://groups.google.com/group/sqlalchemy.
>>> For more options, visit https://groups.google.com/d/optout.
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups
>> "sqlalchemy" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to sqlalchemy+unsubscr...@googlegroups.com
>> .
>> To post to this group, send email to sqlalchemy@googlegroups.com
>> .
>> Visit this group at http://groups.google.com/group/sqlalchemy.
>> For more options, visit https://groups.google.com/d/optout.
> 
> -- 
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email
> to sqlalchemy+unsubscr...@googlegroups.com
> .
> To post to this group, send email to sqlalchemy@googlegroups.com
> .
> Visit this group at http://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] ORM: walk() related objects

2015-09-10 Thread Pavel S
In the meanwhile, I've implemented similar:

def walk(obj, level=0, memo=None):
memo = memo or set()

if obj not in memo:
yield level, obj

memo.add(obj)

insp = inspect(obj)

for relationship in insp.mapper.relationships:
related = getattr(obj, relationship.key)

if relationship.uselist:
for collection_member in related:
for walk_related in walk(collection_member, level + 1, 
memo):
yield walk_related

elif related is not None:
for walk_related in walk(related, level + 1, memo):
yield walk_related


On Thursday, September 10, 2015 at 3:48:55 PM UTC+2, Michael Bayer wrote:
>
>
>
> On 9/10/15 9:35 AM, Mike Bayer wrote:
>
>
>
> On 9/10/15 8:48 AM, Pavel S wrote:
>
> Let's say, I have declarative classes A, B, C, D.
>
> A is the parent
> B has FK to A
> C has FK to B,
> D has FK to C etc...
>
> I'd like to implement *generic method* walk(obj) which will recursively 
> yield dependent/related objects of obj (which is instance of A).
>
> I know that there is introspection interface inspect(), however I'm don't 
> really understand how to use it properly in my use case.
>
> Shall I do inspect(obj) or rather inspect(obj.__class__) and then somehow 
> apply inspection to obj?
>
> Are there an examples and best practices?
>
> right now you can kind of get this effect using cascade_iterator: 
> http://docs.sqlalchemy.org/en/rel_1_0/orm/mapping_api.html?highlight=cascade_iterator#sqlalchemy.orm.mapper.Mapper.cascade_iterator
>
> the limitation is that right now its based on relationship cascade 
> settings, as that's what it was intended for, so you'd probably want to use 
> "save-update":
>
> insp = inspect(my_object)
> for obj in insp.mapper.cascade_iterator("save-update", insp):
># ...
>
> to implement your own system, the graph of objects is strictly based on 
> relationship.   so walk() is pretty simple:
>
> def walk(obj):
> yield obj
> insp = inspect(obj)
> for relationship in insp.mapper.relationships:
> related = getattr(obj, relationship.key)
> if relationship.uselist:
> for collection_member in related:
> for walk_related in walk(collection_member):
> yield walk_related
> elif related is not None:
> for walk_related in walk(related):
> yield walk_related
>
>
> here's one im putting in the FAQ for now, which solves recursion depth as 
> well as cycles:
>
> def walk(obj):
> stack = [obj]
>
> seen = set()
>
> while stack:
> obj = stack.pop(0)
> if obj in seen:
> continue
> else:
> seen.add(obj)
> yield obj
> insp = inspect(obj)
> for relationship in insp.mapper.relationships:
> related = getattr(obj, relationship.key)
> if relationship.uselist:
> stack.extend(related)
> elif related is not None:
> stack.append(related)
>
>
>
>
>
>
>
>
>
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sqlalchemy+...@googlegroups.com .
> To post to this group, send email to sqlal...@googlegroups.com 
> .
> Visit this group at http://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.
>
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sqlalchemy+...@googlegroups.com .
> To post to this group, send email to sqlal...@googlegroups.com 
> .
> Visit this group at http://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] ORM: walk() related objects

2015-09-10 Thread Mike Bayer



On 9/10/15 10:13 AM, Ladislav Lenart wrote:

Hello.

Just a really, really tiny and pedantic correction... The stack variable in the
code is in fact a queue. This could potentially surprise some users / readers.

To fix, please do one of the following:
* Rename stack local var to queue.
* Use stack.pop() to pop the last element from the stack.


there really should be some other name, because all the time, I have 
routines like this where even dynamically within the routine, the pop(0) 
is a pop() or vice-versa, because we'd like the iteration to work one 
way or another.  Changing pop(0) to pop() here means we are doing 
depth-first instead of breadth-first.   So.  Some word that means 
"collection of things to operate upon"?  I've seen "work" used.
"buffer" ?  eh.




HTH,

Ladislav Lenart


On 10.9.2015 15:48, Mike Bayer wrote:


On 9/10/15 9:35 AM, Mike Bayer wrote:


On 9/10/15 8:48 AM, Pavel S wrote:

Let's say, I have declarative classes A, B, C, D.

A is the parent
B has FK to A
C has FK to B,
D has FK to C etc...

I'd like to implement _generic method_ walk(obj) which will recursively yield
dependent/related objects of obj (which is instance of A).

I know that there is introspection interface inspect(), however I'm don't
really understand how to use it properly in my use case.

Shall I do inspect(obj) or rather inspect(obj.__class__) and then somehow
apply inspection to obj?

Are there an examples and best practices?

right now you can kind of get this effect using cascade_iterator:
http://docs.sqlalchemy.org/en/rel_1_0/orm/mapping_api.html?highlight=cascade_iterator#sqlalchemy.orm.mapper.Mapper.cascade_iterator

the limitation is that right now its based on relationship cascade settings,
as that's what it was intended for, so you'd probably want to use "save-update":

insp = inspect(my_object)
for obj in insp.mapper.cascade_iterator("save-update", insp):
# ...

to implement your own system, the graph of objects is strictly based on
relationship.   so walk() is pretty simple:

def walk(obj):
 yield obj
 insp = inspect(obj)
 for relationship in insp.mapper.relationships:
 related = getattr(obj, relationship.key)
 if relationship.uselist:
 for collection_member in related:
 for walk_related in walk(collection_member):
 yield walk_related
 elif related is not None:
 for walk_related in walk(related):
 yield walk_related

here's one im putting in the FAQ for now, which solves recursion depth as well
as cycles:

 def walk(obj):
 stack = [obj]

 seen = set()

 while stack:
 obj = stack.pop(0)
 if obj in seen:
 continue
 else:
 seen.add(obj)
 yield obj
 insp = inspect(obj)
 for relationship in insp.mapper.relationships:
 related = getattr(obj, relationship.key)
 if relationship.uselist:
 stack.extend(related)
 elif related is not None:
 stack.append(related)











--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to sqlalchemy+unsubscr...@googlegroups.com
.
To post to this group, send email to sqlalchemy@googlegroups.com
.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to sqlalchemy+unsubscr...@googlegroups.com
.
To post to this group, send email to sqlalchemy@googlegroups.com
.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to sqlalchemy+unsubscr...@googlegroups.com
.
To post to this group, send email to sqlalchemy@googlegroups.com
.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.




--
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at