[sqlalchemy] backrefs

2012-01-26 Thread Kent
Is there a straightforward way to determine if a RelationshipProperty
has a corresponding "reverse" (backref)?

-- 
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 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Backrefs vs. defining the relationships "by hand"

2011-02-24 Thread Hector Blanco
It was a typo! :-)

> They keep the two sides of a relationship in sync on the python side.

I was suspecting using backrefs was better and that it would do some
kind of synchronization like that, yeah... But I was hoping that
someone would say "No, it's the same"... Because now I won't sleep
soundly at night until I change all my code... But hey... This is what
learning while coding has :-) I will have to "expunge" my old ideas
from my brain and update my code... I hope I can quickly flush the
changes, though

Thank you!

2011/2/24 Michael Bayer :
>
> On Feb 24, 2011, at 1:20 PM, Hector Blanco wrote:
>
>> Hello everyone...
>>
>> I'd like to know what do you think it's better: Whether using backrefs
>> or "manually" defining the relationships one by one. Are the backrefs
>> useful to code less code or do they have other advantages?
>>
>> I.e.: Let's say I have a User and a UserGroup class with (initially)
>> the relationships defined by hand:
>>
>> class User(declarativeBase):
>>       __tablename__ = "users"
>>
>>       _id = Column("id", Integer, primary_key=True)
>>       _email = Column("email", String(60))
>>       _userName = Column("user_name", String(50), unique=True, 
>> nullable=False)
>>       _password = Column("password", String(64), nullable=False)
>>       _userGroupId = Column("user_group_id", Integer, 
>> ForeignKey("user_groups.id"))
>>
>>       _userGroup = relationship("UserGroup", uselist=False)
>>
>> class UserGroup(declarativeBase):
>>       __tablename__ = "user_groups"
>>
>>       _id = Column("id", Integer, primary_key=True)
>>       _name = Column("name", String(50))
>>
>>       _users = relationship("User", order_by=lambda:User.userName,
>> cascade="all, delete", collection_class=set)
>>
>>
>> If, instead, I define that _users (in the UserGroup class) as a backref:
>>
>>
>> class User(declarativeBase):
>>       __tablename__ = "users"
>>
>>       _id = Column("id", Integer, primary_key=True)
>>       _email = Column("email", String(60))
>>       _userName = Column("user_name", String(50), unique=True, 
>> nullable=False)
>>       _password = Column("password", String(64), nullable=False)
>>       _userGroupId = Column("user_group_id", Integer, 
>> ForeignKey("user_groups.id"))
>>
>>
>>       _userGroup = relationship("UserGroup", uselist=False, backref=backref(
>>               backref = backref("_users",
>>                       order_by=lambda:User._userName,
>>                       cascade="all, delete",
>>                       collection_class=set
>>               )
>>         ))
>
> is that correct that there is backref(backref=backref()) up there ?   clearly 
> that's not how it was intended to be used. unless its a typo.
>
>>
>> and, at a certain point I want to create a resetUsers() method in the
>> UserGroup class (to empty the "_users" set) I have to add the users in
>> that set to the session first and then reset it:
>>
>> class UserGroup(declarativeBase):
>>       # Yadda, yadda yadda
>>
>>       def resetUsers(self):
>>               Database.Session().add_all(self._users)
>>               self._users = set()
>>
>> That doesn't happen with the UserGroup._users being a relationship on
>> its own (not a backref). I can just do self._users = set() and it
>> seems to work fine. The database looks consistent to me, and all that.
>>
>> I'd like to know if I'm missing something, or if using backrefs is
>> better for some reason I don't know yet.
>>
>> Any advice will be deeply appreciated. Thank you in advance.
>
> backref means that there are two relationships() set up that have a 
> "back_populates" relationship to each other - you can also configure this as 
> two distinct relationships with back_populates:
>
> class A(...):
>    bar = relationship("B", back_populates="foo")
>
> class B(...):
>   foo = relationship("A", back_populates="bar")
>
>
> This means appending to one results in an append, or set, on the other, and 
> vice versa, and similar for removes.    They keep the two sides of a 
> relationship in sync on the python side.    That said it is optional, but if 
> you were to mutate both sides, both mutations would have an effect during 
> flush.
>
>
>
>
> --
> 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 
> sqlalchemy+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://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 sqlalchemy@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] Backrefs vs. defining the relationships "by hand"

2011-02-24 Thread Michael Bayer

On Feb 24, 2011, at 1:20 PM, Hector Blanco wrote:

> Hello everyone...
> 
> I'd like to know what do you think it's better: Whether using backrefs
> or "manually" defining the relationships one by one. Are the backrefs
> useful to code less code or do they have other advantages?
> 
> I.e.: Let's say I have a User and a UserGroup class with (initially)
> the relationships defined by hand:
> 
> class User(declarativeBase):
>   __tablename__ = "users"
> 
>   _id = Column("id", Integer, primary_key=True)
>   _email = Column("email", String(60))
>   _userName = Column("user_name", String(50), unique=True, nullable=False)
>   _password = Column("password", String(64), nullable=False)
>   _userGroupId = Column("user_group_id", Integer, 
> ForeignKey("user_groups.id"))
> 
>   _userGroup = relationship("UserGroup", uselist=False)
> 
> class UserGroup(declarativeBase):
>   __tablename__ = "user_groups"
> 
>   _id = Column("id", Integer, primary_key=True)
>   _name = Column("name", String(50))
> 
>   _users = relationship("User", order_by=lambda:User.userName,
> cascade="all, delete", collection_class=set)
> 
> 
> If, instead, I define that _users (in the UserGroup class) as a backref:
> 
> 
> class User(declarativeBase):
>   __tablename__ = "users"
> 
>   _id = Column("id", Integer, primary_key=True)
>   _email = Column("email", String(60))
>   _userName = Column("user_name", String(50), unique=True, nullable=False)
>   _password = Column("password", String(64), nullable=False)
>   _userGroupId = Column("user_group_id", Integer, 
> ForeignKey("user_groups.id"))
> 
> 
>   _userGroup = relationship("UserGroup", uselist=False, backref=backref(
>   backref = backref("_users",
>   order_by=lambda:User._userName,
>   cascade="all, delete",
>   collection_class=set
>   )
> ))

is that correct that there is backref(backref=backref()) up there ?   clearly 
that's not how it was intended to be used. unless its a typo.  

> 
> and, at a certain point I want to create a resetUsers() method in the
> UserGroup class (to empty the "_users" set) I have to add the users in
> that set to the session first and then reset it:
> 
> class UserGroup(declarativeBase):
>   # Yadda, yadda yadda
> 
>   def resetUsers(self):
>   Database.Session().add_all(self._users)
>   self._users = set()
> 
> That doesn't happen with the UserGroup._users being a relationship on
> its own (not a backref). I can just do self._users = set() and it
> seems to work fine. The database looks consistent to me, and all that.
> 
> I'd like to know if I'm missing something, or if using backrefs is
> better for some reason I don't know yet.
> 
> Any advice will be deeply appreciated. Thank you in advance.

backref means that there are two relationships() set up that have a 
"back_populates" relationship to each other - you can also configure this as 
two distinct relationships with back_populates:

class A(...):
bar = relationship("B", back_populates="foo")

class B(...):
   foo = relationship("A", back_populates="bar")


This means appending to one results in an append, or set, on the other, and 
vice versa, and similar for removes.They keep the two sides of a 
relationship in sync on the python side.That said it is optional, but if 
you were to mutate both sides, both mutations would have an effect during flush.




-- 
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 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Backrefs vs. defining the relationships "by hand"

2011-02-24 Thread Hector Blanco
Hello everyone...

I'd like to know what do you think it's better: Whether using backrefs
or "manually" defining the relationships one by one. Are the backrefs
useful to code less code or do they have other advantages?

I.e.: Let's say I have a User and a UserGroup class with (initially)
the relationships defined by hand:

class User(declarativeBase):
__tablename__ = "users"

_id = Column("id", Integer, primary_key=True)
_email = Column("email", String(60))
_userName = Column("user_name", String(50), unique=True, nullable=False)
_password = Column("password", String(64), nullable=False)
_userGroupId = Column("user_group_id", Integer, 
ForeignKey("user_groups.id"))

_userGroup = relationship("UserGroup", uselist=False)

class UserGroup(declarativeBase):
__tablename__ = "user_groups"

_id = Column("id", Integer, primary_key=True)
_name = Column("name", String(50))

_users = relationship("User", order_by=lambda:User.userName,
cascade="all, delete", collection_class=set)


If, instead, I define that _users (in the UserGroup class) as a backref:


class User(declarativeBase):
__tablename__ = "users"

_id = Column("id", Integer, primary_key=True)
_email = Column("email", String(60))
_userName = Column("user_name", String(50), unique=True, nullable=False)
_password = Column("password", String(64), nullable=False)
_userGroupId = Column("user_group_id", Integer, 
ForeignKey("user_groups.id"))


_userGroup = relationship("UserGroup", uselist=False, backref=backref(
backref = backref("_users",
order_by=lambda:User._userName,
cascade="all, delete",
collection_class=set
)
 ))

and, at a certain point I want to create a resetUsers() method in the
UserGroup class (to empty the "_users" set) I have to add the users in
that set to the session first and then reset it:

class UserGroup(declarativeBase):
# Yadda, yadda yadda

def resetUsers(self):
Database.Session().add_all(self._users)
self._users = set()

That doesn't happen with the UserGroup._users being a relationship on
its own (not a backref). I can just do self._users = set() and it
seems to work fine. The database looks consistent to me, and all that.

I'd like to know if I'm missing something, or if using backrefs is
better for some reason I don't know yet.

Any advice will be deeply appreciated. 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 sqlalchemy@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] Backrefs and the identity map

2009-08-03 Thread King Simon-NFHD78

Hi,

Does accessing a backref always have to issue SQL, even if the object to
be loaded already exists in the identity map? For example, if I have a
many-to-one lazy-loaded relationship from Master to Detail with a
backref, the statement "master.details[0].master" will issue SQL for the
'.master' backref, even though it already exists in the session. I know
I can eagerload('details.master'), but I was just wondering if there was
any way of getting the relation mechanism to check the identity map
before issuing the SQL.

Here is an example:


import sqlalchemy as sa
import sqlalchemy.orm as saorm
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

Base.metadata.bind = sa.create_engine('sqlite:///:memory')

class Master(Base):
__tablename__ = 'master'
id = sa.Column(sa.Integer, primary_key=True)


class Detail(Base):
__tablename__ = 'detail'
id = sa.Column(sa.Integer, primary_key=True)
master_id = sa.Column(None, sa.ForeignKey(Master.id))
master = saorm.relation(Master, backref='details')

def dbg(msg):
print "\n %s " % msg

def test():
dbg('SQLAlchemy version: %s' % sa.__version__)
Base.metadata.create_all()
Session = saorm.sessionmaker()
sess = Session()

m = Master()
for i in range(10):
m.details.append(Detail())
sess.add(m)
sess.commit()
sess.close()

Base.metadata.bind.echo = True
sess = Session()
dbg("Getting Master")
m = sess.query(Master).first()
dbg("Getting details")
details = m.details
dbg("Getting master of first detail")
m2 = details[0].master
assert m2 is m
dbg("Getting master again via query.get")
m3 = sess.query(Master).get(m.id)
assert m3 is m2


if __name__ == '__main__':
test()



And here is the output:

 SQLAlchemy version: 0.5.5 

 Getting Master 
2009-08-03 13:17:12,445 INFO sqlalchemy.engine.base.Engine.0x...7ecL
BEGIN
2009-08-03 13:17:12,447 INFO sqlalchemy.engine.base.Engine.0x...7ecL
SELECT master.id AS master_id
FROM master
 LIMIT 1 OFFSET 0
2009-08-03 13:17:12,447 INFO sqlalchemy.engine.base.Engine.0x...7ecL []

 Getting details 
2009-08-03 13:17:12,451 INFO sqlalchemy.engine.base.Engine.0x...7ecL
SELECT detail.id AS detail_id, detail.master_id AS detail_master_id
FROM detail
WHERE ? = detail.master_id
2009-08-03 13:17:12,451 INFO sqlalchemy.engine.base.Engine.0x...7ecL [1]

 Getting master of first detail 
2009-08-03 13:17:12,456 INFO sqlalchemy.engine.base.Engine.0x...7ecL
SELECT master.id AS master_id
FROM master
WHERE master.id = ?
2009-08-03 13:17:12,457 INFO sqlalchemy.engine.base.Engine.0x...7ecL [1]

 Getting master again via query.get 

 Finished 


So "query.get" doesn't issue a query, but "master.details[0].master"
does. Is there any way of making the backref use query.get, and thereby
use the identity map?

Thanks a lot,

Simon






--~--~-~--~~~---~--~~
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 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] backrefs

2008-06-26 Thread az

hi
just an idea: is it possible to have half-baked backref-declarations?

i want to use the SA's way of inventing backrefs from a name, and just 
provide some extra arguments to that invention.

instead now i have a full backref(...) having more or less all of the 
relation(...) arguments, but with additional logic on 
picking/swapping of primaryjoin/secondaryjoin - something that SA 
does internaly in the PropertyLoader constructor.

alternatively, i can patch the backref later, letting SA invent it 
properly and then fix some things - like post_update and remote_side. 
how bad is that?

btw remote_side is not propagated by PropertyLoader constructor - but 
IMO is needed.

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