[sqlalchemy] copying a one-to-many relationship

2008-03-10 Thread Christophe Alexandre
Hi,

 

Assuming you have a one-to-many type of relationship, say one user has
several roles.

 

The underlying role table would hold one foreign key referring to the
user table.

 

A properly written SA ORM allows you to write:

 

user1.roles

 

Now assuming you have just created a new user (user2), what is the
easiest way if you want to copy roles from user1?

 

I tried:

 

user2.roles = user1.roles

 

But then it deletes the roles from user1. Same if I go through a
copy.copy():

 

import copy

user2.roles = copy.copy(user1.roles)

 

Does anyone have an idea? I would like to avoid going through a loop and
creating the roles one by one.

 

Chris


--~--~-~--~~~---~--~~
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: copying a one-to-many relationship

2008-03-10 Thread Christophe Alexandre
Ops, not yet fully awake ... obviously you are right about the m-n
relationship. Thank you for working around it ...

 

Also thank you for your answer it is valid for any 1-n relationship I
would have thought of!

 

Chris

 

From: sqlalchemy@googlegroups.com [mailto:[EMAIL PROTECTED]
On Behalf Of Michael Bayer
Sent: Monday, March 10, 2008 3:00 PM
To: sqlalchemy@googlegroups.com
Subject: [sqlalchemy] Re: copying a one-to-many relationship

 

 

On Mar 10, 2008, at 9:19 AM, Christophe Alexandre wrote:





Hi,

 

Assuming you have a one-to-many type of relationship, say one user has
several roles.

 

The underlying role table would hold one foreign key referring to the
user table.

 

A properly written SA ORM allows you to write:

 

user1.roles

 

Now assuming you have just created a new user (user2), what is the
easiest way if you want to copy roles from user1?

 

I tried:

 

user2.roles = user1.roles

 

But then it deletes the roles from user1. 

 

my first impression is that a relation from users to roles is
typically a many to many.  That you are looking to have the same roles
present on more than one user implies this as well.  But we can still
work with one-to-many.

 





Same if I go through a copy.copy():

 

import copy

user2.roles = copy.copy(user1.roles)

 

copy is going to fail because its copying the full state of each user,
including the primary key, instance key, and probably the _state which
is putting your session into an invalid state.





 

Does anyone have an idea? I would like to avoid going through a loop and
creating the roles one by one.

 

First I'd put a convenience method on Role to handle generating a new
Role object with the same value:

 

def asnew(self):

return Role(self.name, ...)

 

then I'd just use a list comprehension to make the copy:

 

user2.roles = [r.asnew() for r in user.roles]

 

 

 



 


--~--~-~--~~~---~--~~
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: dictionary returning a collection

2008-01-18 Thread Christophe Alexandre

Great!

The solution #3 seems especially appealing ...

Thank you for the comprehensive answer!

-Original Message-
From: sqlalchemy@googlegroups.com [mailto:[EMAIL PROTECTED]
On Behalf Of jason kirtland
Sent: Thursday, January 17, 2008 7:53 PM
To: sqlalchemy@googlegroups.com
Subject: [sqlalchemy] Re: dictionary returning a collection


Christophe Alexandre wrote:
 Dear All,
 
 Send me some study material on DBMS + $100 !
 
 Or if it fits you better, can you please help on the issue described
 below?
 
 The closest situation to what I am facing is described here:

http://www.sqlalchemy.org/docs/04/plugins.html#plugins_associationproxy_
 building
 
 But unfortunately the situation is not close enough to help me.
 
 Now, based on the example above, here is the issue:
 
 stocks = Table(stocks, meta,
Column('symbol', String(10), primary_key=True),
Column('description', String(100), nullable=False),
Column('last_price', Numeric)
 )
 
 brokers = Table(brokers, meta,
Column('id', Integer,primary_key=True),
Column('name', String(100), nullable=False)
 )
 
 holdings = Table(holdings, meta,
   Column('broker_id', Integer,
   ForeignKey('brokers.id'), primary_key=True),
   Column('symbol', String(10),
   ForeignKey('stocks.symbol'), primary_key=True),
   Column('shares', Integer),
   Column('date', DateTime, primary_key=True)  # -- HERE IS THE
 DIFFERENCE
 )
 
 The example in the doc provides a nice way to retrieve one holding:
 holding = broker.holdings[stock]
 
 But what if holdings are parameterized by a new attribute ('date' in
our
 case)?
 
 How would you implement a solution allowing you to do something like
 this:
 
 date = datetime.datetime(2007,1,1)
 holdings = broker.holdingsByDate[date]
 
 where 'holdings' is a collection of what the broker is holding at a
 given date.

A couple approaches come to mind.  How many Holdings rows in total do 
you expect per Broker?

If the number is large, then on-demand querying for chunks of the set by

date could be a good option.  That can be wrapped up in a dict-like 
class with __getattr__ for an interface like holdingsByDate[date].  You 
could cache too, if you wanted.  No mapper relation from Broker-Holding

would be needed, but you'd want Holding-Broker.

If the number is small enough that loading the entire collection of 
associated Holdings per Broker isn't a big deal, then a whole bunch of 
options come to mind, but none of these are built-in.

- A dict-like proxy similar to the large collection approach, except 
scanning .holdings in-memory and filtering by .date on demand

- Add some append/remove event handlers to the collection backing 
.holding, and use them to maintain a obj.holdingsByDate dictionary 
transparently

- Use the collections framework to build a fully featured partitioned 
collection type

These are all pretty simple to implement- something like #2 is just a 
few lines of code.

An implementation of #3 (a dictionary of lists with full instrumented 
goodness) is probably not a ton of work at all and could make a good 
addition to either the collections or ext package.




--~--~-~--~~~---~--~~
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: dictionary returning a collection

2008-01-18 Thread Christophe Alexandre

Dear All,

Just to let you know how I solved my problem: according to the solution
#3 described below by Jason, I created in my local sqlalchemy
installation a MultiValuedMappedCollection class in the
sqlalchemy.orm.collections package Based on the MappedCollection class.

The newly created class can then be referenced in a method:

def multi_valued_mapped_collection(keyfunc):
return lambda: MultiValuedMappedCollection(keyfunc)

(Similarly to the existing mapped_collection(keyfunc))

The only change I brought to the MappedCollection resides in the 'set'
method and was really simple (a little too simplistic to be included
as-is in the framework I think):

def set(self, value, _sa_initiator=None):
Add a value to the collection of multi-values, with a key
provided by this instance's keyfunc.

key = self.keyfunc(value)
if not self.has_key(key):
  # creates a list on the fly if needed
  self.__setitem__(key, [], _sa_initiator)
self.__getitem__(key).append(value)
set = collection.internally_instrumented(set)
set = collection.appender(set)

So that the inherited dict simply holds a list (created on-the-fly)
instead of the value directly. Values are then accumulated in the
existing list each time dict[key] = value is called.

- not sure that people want to have something exactly like this
eventually embedded in the framework, but it helped in solving my
short-term needs and may also help any good soul willing to implement it
properly ...

Bottom-line:
---

Using a declaration like this in the Broker mapper:
'holdingsByDate': relation(Holding,

collection_class=attribute_multi_valued_mapped_collection('date'))

it allows me to write in my app:
date = datetime.datetime(2007,1,1)
holdings = broker.holdingsByDate[date]


Christophe

-Original Message-
From: sqlalchemy@googlegroups.com [mailto:[EMAIL PROTECTED]
On Behalf Of jason kirtland
Sent: Thursday, January 17, 2008 7:53 PM
To: sqlalchemy@googlegroups.com
Subject: [sqlalchemy] Re: dictionary returning a collection


Christophe Alexandre wrote:
 Dear All,
 
 Send me some study material on DBMS + $100 !
 
 Or if it fits you better, can you please help on the issue described
 below?
 
 The closest situation to what I am facing is described here:

http://www.sqlalchemy.org/docs/04/plugins.html#plugins_associationproxy_
 building
 
 But unfortunately the situation is not close enough to help me.
 
 Now, based on the example above, here is the issue:
 
 stocks = Table(stocks, meta,
Column('symbol', String(10), primary_key=True),
Column('description', String(100), nullable=False),
Column('last_price', Numeric)
 )
 
 brokers = Table(brokers, meta,
Column('id', Integer,primary_key=True),
Column('name', String(100), nullable=False)
 )
 
 holdings = Table(holdings, meta,
   Column('broker_id', Integer,
   ForeignKey('brokers.id'), primary_key=True),
   Column('symbol', String(10),
   ForeignKey('stocks.symbol'), primary_key=True),
   Column('shares', Integer),
   Column('date', DateTime, primary_key=True)  # -- HERE IS THE
 DIFFERENCE
 )
 
 The example in the doc provides a nice way to retrieve one holding:
 holding = broker.holdings[stock]
 
 But what if holdings are parameterized by a new attribute ('date' in
our
 case)?
 
 How would you implement a solution allowing you to do something like
 this:
 
 date = datetime.datetime(2007,1,1)
 holdings = broker.holdingsByDate[date]
 
 where 'holdings' is a collection of what the broker is holding at a
 given date.

A couple approaches come to mind.  How many Holdings rows in total do 
you expect per Broker?

If the number is large, then on-demand querying for chunks of the set by

date could be a good option.  That can be wrapped up in a dict-like 
class with __getattr__ for an interface like holdingsByDate[date].  You 
could cache too, if you wanted.  No mapper relation from Broker-Holding

would be needed, but you'd want Holding-Broker.

If the number is small enough that loading the entire collection of 
associated Holdings per Broker isn't a big deal, then a whole bunch of 
options come to mind, but none of these are built-in.

- A dict-like proxy similar to the large collection approach, except 
scanning .holdings in-memory and filtering by .date on demand

- Add some append/remove event handlers to the collection backing 
.holding, and use them to maintain a obj.holdingsByDate dictionary 
transparently

- Use the collections framework to build a fully featured partitioned 
collection type

These are all pretty simple to implement- something like #2 is just a 
few lines of code.

An implementation of #3 (a dictionary of lists with full instrumented 
goodness) is probably not a ton of work at all and could make a good 
addition to either the collections or ext package.





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

[sqlalchemy] dictionary returning a collection

2008-01-17 Thread Christophe Alexandre

Dear All,

Send me some study material on DBMS + $100 !

Or if it fits you better, can you please help on the issue described
below?

The closest situation to what I am facing is described here:
http://www.sqlalchemy.org/docs/04/plugins.html#plugins_associationproxy_
building

But unfortunately the situation is not close enough to help me.

Now, based on the example above, here is the issue:

stocks = Table(stocks, meta,
   Column('symbol', String(10), primary_key=True),
   Column('description', String(100), nullable=False),
   Column('last_price', Numeric)
)

brokers = Table(brokers, meta,
   Column('id', Integer,primary_key=True),
   Column('name', String(100), nullable=False)
)

holdings = Table(holdings, meta,
  Column('broker_id', Integer,
ForeignKey('brokers.id'), primary_key=True),
  Column('symbol', String(10),
ForeignKey('stocks.symbol'), primary_key=True),
  Column('shares', Integer),
  Column('date', DateTime, primary_key=True)  # -- HERE IS THE
DIFFERENCE
)

The example in the doc provides a nice way to retrieve one holding:
holding = broker.holdings[stock]

But what if holdings are parameterized by a new attribute ('date' in our
case)?

How would you implement a solution allowing you to do something like
this:

date = datetime.datetime(2007,1,1)
holdings = broker.holdingsByDate[date]

where 'holdings' is a collection of what the broker is holding at a
given date.

Thank you for your help,

Christophe

--~--~-~--~~~---~--~~
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: access mapped object attributes

2007-11-06 Thread Christophe Alexandre

Hi,

I am also interested in retrieving all the attributes resulting from the
ORM.

The loop on '.c' will list only the database columns. Is there a way to
list the object attributes?

Thanks a lot for your help,

Chris

-Original Message-
From: sqlalchemy@googlegroups.com [mailto:[EMAIL PROTECTED]
On Behalf Of Paul Johnston
Sent: Monday, November 05, 2007 8:45 PM
To: sqlalchemy@googlegroups.com
Subject: [sqlalchemy] Re: access mapped object attributes


Hi,

Given a Message object, do I have a way to retrieve all the attributes
that result from the database mapping? 

Try this:

for col in Message.c:
...

Paul


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