[sqlalchemy] relationships for no-table-related Class

2010-11-11 Thread neurino
I have a tree structure

Root
  |
  +--Area
  ||
  |+--SubArea
  |||
  ||+--Item
  |||
  ||+--Item
  ||
  |+--SubArea
  | |
  | +--Item
  | |
  | +--Item
  |
  +--Area
   |
   +--SubArea
   ||
   |+--Item
   ||
   |+--Item
   |
   +--SubArea
|
+--Item
|
+--Item

The tree structure corresponds to slqalchemy db tables `areas`,
`subareas` and `items`.

Something like this:

mapper(Area, areas_table, properties={
'subareas': relationship(SubArea, backref='parent'),
})
mapper(SubArea, subareas__table, properties={
'items': relationship(Item, backref='parent'),
})
mapper(Item, items_table)

so each Area instance will have a `subareas` list and each SubArea
will have a `items` list,

also I easyly get a backref `parent` from Item to parent SubArea and
from
SubArea to parent Area.

But this won't be for Root: it will not have a `areas` list in Root
nor its areas will have a parent reference to Root.

The quick-and-dirty solution is to do this in Root:

self.areas = query(Area).all()
for area in self.areas:
area.parent = self

But it won't be the same thing as sqlalchemy `relationship` attributes
so:
are there alternative solutions more sqlalchemy-like?

Any tip appreciated!

Thank you for your support

Greetings
neurino

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: Delete and Concrete Table Inheritance

2010-11-11 Thread Mene
Yes, that was what I searched for. My Solution now is to use pythons
introspection like this:

for dataClass in Master.__subclasses__():
table = sqlalchemy.orm.class_mapper(dataClass).local_table
delete_query = table.delete(). \
where(...)
session.execute(delete_query, dict(...))

I was searching for something in sqlalchemy, that does the same by
calling something like:
Master.deleteAll().where(...) or similar

Thanks for the help!


On 10 Nov., 15:43, Michael Bayer mike...@zzzcomputing.com wrote:
 On Nov 10, 2010, at 8:00 AM, Mene wrote:

  Yes, I definitely want to emit a DELETE statement. The Problem is that
  calling master.delete() only gives an delete statement for the master
  table. However, I need n querys: DELETE child1... , DELETE child2 and
  so on.

 OK, so I think there's another question that you mean to be asking here, 
 since I'm sure its obvious that to emit a DELETE statement for child1, 
 child2, etc., you do the same thing for those Table objects:

         child1.delete().where(...)
         child2.delete().where(...)
         child3.delete().where(...)
         ... etc

 I think the question you want here is how do I get at all the Table objects 
 in an inheritance hierarchy given only the base class?

         for mapper in master_mapper.polymorphic_iterator():
             Session.execute(mapper.local_table.delete().where(...))

 Note that concrete inheritance is the least wieldy inheritance scheme.  If 
 you were using joined table inheritance, you could configure ON DELETE 
 CASCADE on all your tables and you could then emit a single DELETE just for 
 the master table that would automatically delete from all related tables.





  On 8 Nov., 20:31, Michael Bayer mike...@zzzcomputing.com wrote:
  On Nov 8, 2010, at 11:02 AM, Mene wrote:

  Hi all,
  I have some 'child' tables which inherit from the same 'master' table,
  now I'd like to delete some entries from all tables. The 'where'-part
  comes solely from the master table.
  I have decided to use Concrete Table Inheritance since I don't need
  the inheritance at points other than deleting, but I expect the tables
  to have a lot of entries and at the moment I don't know how many child
  tables I will have in the future. Also the delete process won't occur
  often.

  Each table has a compound primary key of user and room.
  I use version 0.4.8 (and I can't change this)

  I need a delete statement that deletes according to user_id and the
  length of the room identifier.
  Also master is only an abstract class, so I don't need to have a table
  in my database (AFAIK).

  There's only two choices here, you can either load the objects with the 
  ORM and individually pass them to session.delete(), or you can emit DELETE 
  statements against the tables directly using SQL expressions or strings.   
  The SQL expression would be along the lines of 
  Session.execute(master.delete().where(...)).

  master = Table('master', metadata,
     Column('user_id', Integer, ForeignKey('user.user_id',
  ondelete='CASCADE'), primary_key=True),
     Column('room', Unicode(16), ForeignKey('room.id'),
  primary_key=True)
  )

  child1 = Table('child1', metadata,
     Column('user_id', Integer, ForeignKey('user.user_id',
  ondelete='CASCADE'), primary_key=True),
     Column('room', Unicode(16), ForeignKey('room.id'),
  primary_key=True),
     Column('child1_data', Unicode(16))
  )

  child2 = Table('child2', metadata,
     Column('user_id', Integer, ForeignKey('user.user_id',
  ondelete='CASCADE'), primary_key=True),
     Column('room', Unicode(16), ForeignKey('room.id'),
  primary_key=True),
     Column('child2_data', Unicode(16))
  )

  join = polymorphic_union({
     'master': master,
     'child1': child1,
     'child2': child2
  }, 'type', 'pjoin')

  master_mapper = mapper(Master, master, with_polymorphic=('*',
  vote_join), \
     polymorphic_on=vote_join.c.type, polymorphic_identity='vote_data')

  child1_mapper = mapper(Child1, child1, inherits=master, \
     concrete=True, polymorphic_identity='child1')

  child2_mapper = mapper(Child2, child2, inherits=master, \
     concrete=True, polymorphic_identity='child2')

  Thanks for your time,
  Mene

  --
  You received this message because you are subscribed to the Google Groups 
  sqlalchemy group.
  To post to this group, send email to sqlalch...@googlegroups.com.
  To unsubscribe from this group, send email to 
  sqlalchemy+unsubscr...@googlegroups.com.
  For more options, visit this group 
  athttp://groups.google.com/group/sqlalchemy?hl=en.

  --
  You received this message because you are subscribed to the Google Groups 
  sqlalchemy group.
  To post to this group, send email to sqlalch...@googlegroups.com.
  To unsubscribe from this group, send email to 
  sqlalchemy+unsubscr...@googlegroups.com.
  For more options, visit this group 
  athttp://groups.google.com/group/sqlalchemy?hl=en.

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

[sqlalchemy] how to graph database structure?

2010-11-11 Thread Nagy Viktor
Hi,

I've reflected a database, and it would like to get a graphic representation
of it something like the graph_models command in django command extensions.

The best would be if the tool could create the graphics without a database
connection, simply using my metadata for example.

I've googled for this, but couldn't find anything seemingly up-to-date.

What would be your suggestion?

thanks, Viktor

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] how to graph database structure?

2010-11-11 Thread Tamás Bajusz
On Thu, Nov 11, 2010 at 12:59 PM, Nagy Viktor viktor.n...@toolpart.hu wrote:
 Hi,
 I've reflected a database, and it would like to get a graphic representation
 of it something like the graph_models command in django command extensions.
 The best would be if the tool could create the graphics without a database
 connection, simply using my metadata for example.
 I've googled for this, but couldn't find anything seemingly up-to-date.
 What would be your suggestion?

http://www.sqlalchemy.org/trac/wiki/UsageRecipes/SchemaDisplay

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Two relationships with a same backref name. Is that (even) possible or I got everything wrong?

2010-11-11 Thread Hector Blanco
I have a class that has two relationships to the same type of objects.
One of the relationships will store objects of type VR and the other
objects with a type CC. One object can only be in one of the lists
(relationships) at the same time:

This is the container class and its two relationships:

class Container(rdb.Model):
rdb.metadata(metadata)
rdb.tablename(containers)

id = Column(id, Integer, primary_key=True)

relation1 = relationship(MyObject,
uselist=True,
primaryjoin=lambda: and_((MyObject.id == MyObject.containerId),
(MyObject._type == VR)),
cascade=all, delete, delete-orphan
)

relation2 = relationship(MyObject,
uselist=True,
primaryjoin=lambda: and_((MyObject.id == MyObject.containerId),
(MyObject._type == CC)),
cascade=all, delete, delete-orphan
)

I don't think there's need to mention, but, MyObject.containerId is
a ForeignKey pointing to the Container.id.

I'd like to know if there's a way to create a backref so I will be
able to access the container through the MyObject class. The idea
would be having something like:

relation1 = relationship(MyObject,
uselist=True,
primaryjoin=lambda: and_((MyObject.id == MyObject.containerId),
(MyObject._type == VR)),
cascade=all, delete, delete-orphan,
backref=backref('container', order_by=id)
)

relation2 = relationship(MyObject,
uselist=True,
primaryjoin=lambda: and_((MyObject.id == MyObject.containerId),
(MyObject._type == CC)),
cascade=all, delete, delete-orphan,
backref=backref('container', order_by=id)
)

But of course, that fails because it's trying to add two .container
fields to the MyObject class.

I have also seen that you can define joins in the backref, but I
haven't been able to find examples about how to define it. And I am
still not very sure that that would allow me to have to backrefs with
the same name/identifier.

I just need to know if it's even possible having two backrefs with the
same name. Actually, a you really got the whole concept wrong may
help too (if that's the case) . If it's doable, does any of you know
where can I find examples of advanced backref usage? With primary
joins, secondary joins and all that juicy stuff...

Thank you in advance!!

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Re: Odd many-to-one problem

2010-11-11 Thread Mike Conley
For cases like this I have found something like this to be useful

http://www.sqlalchemy.org/docs/orm/relationships.html#multiple-relationships-against-the-same-parent-child

using lazy loading and viewonly=True as needed

I found this to be clearer than column property because it fits cleanly with
the rest of the relationship configuration.


-- 
Mike Conley

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: Odd many-to-one problem

2010-11-11 Thread Jonathan Gardner
relationship() expects a class or a mapper instance, not a string. I
got this error:

ArgumentError: relationship 'available_deals' expects a class or a
mapper argument (received: type 'str')

On Nov 10, 4:46 pm, Sergey V. sergey.volob...@gmail.com wrote:
  The twist is that I've spread out my tables and ORM classes across
  several files. I've tried to keep it so that I don't have circular
  dependencies. That means I've defined Merchant first, and then Deal
  later, in separate files

 To avoid problems with imports and dependencies you can pass strings
 to the relationship function instead of the actual classes:

 mapper(Deal, deals, properties=dict(
       merchant=relationship('Merchant', backref='deals'),
   ))

 This greatly simplifies everything if you split your classes into
 separate files.

 Regarding 'available_deals', 'deleted_deals' etc. - the approach with
 properties is sub-optimal. Consider a merchant having thousands of
 deals, only a few of which are available - the method would have to
 fetch all those deals only to discard most of them. Also, that won't
 work with eager loading. The optimal way would be to make SA to
 generate a query like SELECT ... FROM Deals WHERE ... AND deleted=1
 which would return only the records we're interested in. I'm sure it's
 possible but I'll leave it to you to find it in SA docs :) When you
 find it please post it here :)

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: Odd many-to-one problem

2010-11-11 Thread Jonathan Gardner
That is useful for mapping single or combined columns to an attribute.
Here, I want to map entire objects.

On Nov 10, 10:20 pm, Eric Ongerth ericonge...@gmail.com wrote:
 Good point, Sergey.

 Here is the relevant documentation regarding mapping attributes to
 selects:http://www.sqlalchemy.org/docs/orm/mapper_config.html?highlight=arbit...

 On Nov 10, 4:46 pm, Sergey V. sergey.volob...@gmail.com wrote:

   The twist is that I've spread out my tables and ORM classes across
   several files. I've tried to keep it so that I don't have circular
   dependencies. That means I've defined Merchant first, and then Deal
   later, in separate files

  To avoid problems with imports and dependencies you can pass strings
  to the relationship function instead of the actual classes:

  mapper(Deal, deals, properties=dict(
        merchant=relationship('Merchant', backref='deals'),
    ))

  This greatly simplifies everything if you split your classes into
  separate files.

  Regarding 'available_deals', 'deleted_deals' etc. - the approach with
  properties is sub-optimal. Consider a merchant having thousands of
  deals, only a few of which are available - the method would have to
  fetch all those deals only to discard most of them. Also, that won't
  work with eager loading. The optimal way would be to make SA to
  generate a query like SELECT ... FROM Deals WHERE ... AND deleted=1
  which would return only the records we're interested in. I'm sure it's
  possible but I'll leave it to you to find it in SA docs :) When you
  find it please post it here :)

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: Odd many-to-one problem

2010-11-11 Thread Jonathan Gardner
This is what I need to do, except the Merchant object is defined
before the Deal object. In the example in the documentation, I have
mapped User before I have mapped Address.

On Nov 11, 10:25 am, Mike Conley mconl...@gmail.com wrote:
 For cases like this I have found something like this to be useful

 http://www.sqlalchemy.org/docs/orm/relationships.html#multiple-relati...

 using lazy loading and viewonly=True as needed

 I found this to be clearer than column property because it fits cleanly with
 the rest of the relationship configuration.


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Re: Odd many-to-one problem

2010-11-11 Thread Mike Conley
If it's simply a matter of sequence of how code is organized:

1. Define Merchants table and mappers
2. Define Deals table and mappers
3. Add relations to Merchant
All of this can be in separate files if needed; just import right
definitions where needed.


metadata = MetaData()

merchants = Table('merchants', metadata,
Column('id', Integer, primary_key=True),
Column('name', String)
)

class Merchant(object):
pass

mapper(Merchant, merchants)


deals = Table('deals', metadata,
Column('id', Integer, primary_key=True),
Column('merch_id', Integer, ForeignKey('merchants.id')),
Column('deal_status', String(10))
)

class Deal(object):
pass

mapper(Deal, deals)


Merchant.all_deals = relation(Deal, backref='merchant')
Merchant.active_deals = relation(Deal, primaryjoin=
and_(merchants.c.id==deals.c.merch_id,
deals.c.deal_status=='active'))



This is one advantage of using declarative because the primaryjoin can be
defined as a string that will not be compiled until later. That can be
deferred until after everything is defined.

-- 
Mike Conley




On Thu, Nov 11, 2010 at 1:33 PM, Jonathan Gardner 
jgard...@jonathangardner.net wrote:

 This is what I need to do, except the Merchant object is defined
 before the Deal object. In the example in the documentation, I have
 mapped User before I have mapped Address.



-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: Odd many-to-one problem

2010-11-11 Thread Sergey V.

 relationship() expects a class or a mapper instance, not a string. I
 got this error:

 ArgumentError: relationship 'available_deals' expects a class or a
 mapper argument (received: type 'str')

Hmm... I'm not sure what I'm doing wrong but passing strings to
relation() definitely works for me:


class Host(Base):

__tablename__ = 'hosts'
id = sa.Column(sa.Integer, primary_key = True)
...
datacentre_id = sa.Column(sa.Integer,
sa.ForeignKey('datacentres.id'))
datacentre = sa.orm.relation('Datacentre', backref='hosts')

Can it be because I'm using declarative? In my case I don't even need
to import Datacentre class before I declare Host class.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: Two relationships with a same backref name. Is that (even) possible or I got everything wrong?

2010-11-11 Thread Eric Ongerth
Hi Hector,

If I'm not mistaken, everywhere you wrote
(MyObject.id==MyObject.containerId),
you meant to write: (Container.id==MyObject.containerId).

Instead of the backref technique, why not just create the MyObject--
Container relationship a single time in your MyObject class.  That
should be able to coexist with your first code example (with no
backrefs).


On Nov 11, 8:16 am, Hector Blanco white.li...@gmail.com wrote:
 I have a class that has two relationships to the same type of objects.
 One of the relationships will store objects of type VR and the other
 objects with a type CC. One object can only be in one of the lists
 (relationships) at the same time:

 This is the container class and its two relationships:

 class Container(rdb.Model):
         rdb.metadata(metadata)
         rdb.tablename(containers)

         id = Column(id, Integer, primary_key=True)

         relation1 = relationship(MyObject,
                 uselist=True,
                 primaryjoin=lambda: and_((MyObject.id == 
 MyObject.containerId),
                                 (MyObject._type == VR)),
                 cascade=all, delete, delete-orphan
         )

         relation2 = relationship(MyObject,
                 uselist=True,
                 primaryjoin=lambda: and_((MyObject.id == 
 MyObject.containerId),
                                 (MyObject._type == CC)),
                 cascade=all, delete, delete-orphan
         )

 I don't think there's need to mention, but, MyObject.containerId is
 a ForeignKey pointing to the Container.id.

 I'd like to know if there's a way to create a backref so I will be
 able to access the container through the MyObject class. The idea
 would be having something like:

         relation1 = relationship(MyObject,
                 uselist=True,
                 primaryjoin=lambda: and_((MyObject.id == 
 MyObject.containerId),
                                 (MyObject._type == VR)),
                 cascade=all, delete, delete-orphan,
                 backref=backref('container', order_by=id)
         )

         relation2 = relationship(MyObject,
                 uselist=True,
                 primaryjoin=lambda: and_((MyObject.id == 
 MyObject.containerId),
                                 (MyObject._type == CC)),
                 cascade=all, delete, delete-orphan,
                 backref=backref('container', order_by=id)
         )

 But of course, that fails because it's trying to add two .container
 fields to the MyObject class.

 I have also seen that you can define joins in the backref, but I
 haven't been able to find examples about how to define it. And I am
 still not very sure that that would allow me to have to backrefs with
 the same name/identifier.

 I just need to know if it's even possible having two backrefs with the
 same name. Actually, a you really got the whole concept wrong may
 help too (if that's the case) . If it's doable, does any of you know
 where can I find examples of advanced backref usage? With primary
 joins, secondary joins and all that juicy stuff...

 Thank you in advance!!

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: Odd many-to-one problem

2010-11-11 Thread Eric Ongerth
Mike, what you set forth is more of what I was actually trying to
bring into the discussion (having used that same technique myself),
rather than the link I gave above.  I need to get more sleep and check
my doc references more carefully!


On Nov 11, 1:39 pm, Mike Conley mconl...@gmail.com wrote:
 If it's simply a matter of sequence of how code is organized:

 1. Define Merchants table and mappers
 2. Define Deals table and mappers
 3. Add relations to Merchant
 All of this can be in separate files if needed; just import right
 definitions where needed.

 metadata = MetaData()

 merchants = Table('merchants', metadata,
     Column('id', Integer, primary_key=True),
     Column('name', String)
     )

 class Merchant(object):
     pass

 mapper(Merchant, merchants)

 deals = Table('deals', metadata,
     Column('id', Integer, primary_key=True),
     Column('merch_id', Integer, ForeignKey('merchants.id')),
     Column('deal_status', String(10))
     )

 class Deal(object):
     pass

 mapper(Deal, deals)

 Merchant.all_deals = relation(Deal, backref='merchant')
 Merchant.active_deals = relation(Deal, primaryjoin=
                 and_(merchants.c.id==deals.c.merch_id,
                 deals.c.deal_status=='active'))

 This is one advantage of using declarative because the primaryjoin can be
 defined as a string that will not be compiled until later. That can be
 deferred until after everything is defined.

 --
 Mike Conley

 On Thu, Nov 11, 2010 at 1:33 PM, Jonathan Gardner 

 jgard...@jonathangardner.net wrote:
  This is what I need to do, except the Merchant object is defined
  before the Deal object. In the example in the documentation, I have
  mapped User before I have mapped Address.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.