ForeignKey to User class from identity package

3 views
Skip to first unread message

Ksenia Marasanova

unread,
Nov 20, 2005, 8:02:53 AM11/20/05
to turbo...@googlegroups.com
Hi,

In my model class, I wanted to define ForeignKey to User class from
identity package. But identity uses it's own SQLObject registry -
"turbogears", so it doesn't work.
Is there a better way to link to / extend identity classes?

Thanks
--
Ksenia

william

unread,
Nov 20, 2005, 8:15:21 AM11/20/05
to TurboGears
Personnally, I've subclass the IdentityProvider

my identity provider:
http://projectsmgt.opensource4you.org/ProjectsMgt/file/trunk/projectsmgt/model.py

This way you can design your Users db as you want.

Don't forget to update accordingly the .cfg (
http://projectsmgt.opensource4you.org/ProjectsMgt/file/trunk/dev.cfg)

Maybe not the best method, but very flexible.

William

---
http://www.opensource4you.com

Patrick Lewis

unread,
Nov 20, 2005, 11:57:18 AM11/20/05
to TurboGears
The best I can come up with is to use SQLObjects 'magic attributes'
functionality to fake the foreign key reference. An example:

from turbogears.identity.model.somodel import User

class myUser(SQLObject):

fk_to_user = IntCol()

def _get_user(self):
return User.get(self.fk_to_user)

def _set_user(self, user_obj):
self.fk_to_user = user_obj.id

def _del_user(self):
u=User.get(self.fk_to_user)
u.destroySelf()
self.fk_to_user = None

# Other things you want to implement in your class...

Unless SQLObject defines a way to access other registry classes (which
I couldn't find), I think that's your simplest solution. If your
database supports it, it may be worthwhile to set up the foreign key
reference in your db schema, just to be sure.

Patrick Lewis

unread,
Nov 20, 2005, 12:05:00 PM11/20/05
to TurboGears
Sorry, forgot to make clear that the above allows you to do:

#get the identity user
u = User(1)

#create myUser
mu=myUser(fk_to_user=None)
mu.user=u
# can now reference the attributes of the user through mu
email = mu.user.emailAddress

Ksenia Marasanova

unread,
Nov 20, 2005, 1:33:37 PM11/20/05
to turbo...@googlegroups.com
2005/11/20, Patrick Lewis <ple...@spamcop.net>:
>
> The best I can come up with is to use SQLObjects 'magic attributes'
> functionality to fake the foreign key reference. An example:

That's what I finally did, thanks. The basic identity model works just
fine for my project, so I thought that subclassing IdentityProvider
will be too much work.

But I think that putting TG models in a different registry makes it
unnessesarily difficult, unless SQLObject has some magic function to
change it... Maybe a better way will be just use "TG" prefix for
TurboGear models? The tables have tg_ prefix anyway...

--
Ksenia

Jeff Watkins

unread,
Nov 20, 2005, 2:28:54 PM11/20/05
to turbo...@googlegroups.com
I didn't realise that putting the Identity model into a different registry would make them unavailable to an app developer's model. This seems like a major flaw.

Is there no way to uniquely identify a class using SQLObject? Sort of like using fully qualified names in Java?

On 20 Nov, 2005, at 1:33 pm, Ksenia Marasanova wrote:


But I think that putting TG models in a different registry makes it

unnessesarily difficult, unless SQLObject has some magic function to

change it... Maybe a better way will be just use "TG" prefix for

TurboGear models? The tables have tg_ prefix anyway...


-- 

Jeff Watkins

http://newburyportion.com/


Computers, they're just a fad.



Jorge Godoy

unread,
Nov 20, 2005, 5:23:47 PM11/20/05
to turbo...@googlegroups.com
Jeff Watkins <je...@newburyportion.com> writes:

> I didn't realise that putting the Identity model into a different registry
> would make them unavailable to an app developer's model. This seems like a
> major flaw.

It's a big inconvenience.

> Is there no way to uniquely identify a class using SQLObject? Sort of like
> using fully qualified names in Java?

I didn't get your question, but every class is uniquely identified. You have
packagename.subpackage.class identifying it. You can't have two "User"
classes in the same namespace...

I think I missed your point, though...


--
Jorge Godoy <jgo...@gmail.com>

Patrick Lewis

unread,
Nov 20, 2005, 8:03:15 PM11/20/05
to TurboGears
Not to speak for Jeff, but I wonder if an SQLObject class can natively
refer to another class in a separate registry? For example:

class Foo(SQLObject):
class sqlmeta:
registry='foo'
name = StringCol(length=50)

class Bar(SQLObject):
foo_obj = ForeignKey('foo.Foo')

While this appears to work, as soon as you try to reference
Bar.foo_obj, an exception is thrown.

Traceback (most recent call last):
File "<console>", line 1, in ?
File "<string>", line 1, in <lambda>
AttributeError: 'Bar' object has no attribute '_SO_class_foo'

I imagine subcassing is a pain too, because your subclass is
automatically in the parent's registry, and can't refer to your
applications registry.

If you can't refer to another registry, I guess I don't really see the
point of it (I was unaware this was how the registry worked, too).
Sure, it prevents namespace clashes, but interoperability between
classes would seem to be pretty important. I'm hoping this is just a
lack of understanding on my part.

Perhaps this is a question that should be asked on the SQLObject list?

Tim Lesher

unread,
Nov 21, 2005, 9:50:12 AM11/21/05
to turbo...@googlegroups.com
On 11/20/05, Patrick Lewis <ple...@spamcop.net> wrote:
> While this appears to work, as soon as you try to reference
> Bar.foo_obj, an exception is thrown.
>
> Traceback (most recent call last):
> File "<console>", line 1, in ?
> File "<string>", line 1, in <lambda>
> AttributeError: 'Bar' object has no attribute '_SO_class_foo'

I see the same issue. It's interesting that if, in an interactive
session, I import both models, then manually set Bar._SO_class_foo =
Foo, everything works.

I haven't figured out how to translate that into a strategy for TG yet.
--
Tim Lesher <tle...@gmail.com>

Dan Jacob

unread,
Nov 25, 2005, 6:54:23 AM11/25/05
to TurboGears

I've found the following works:
from sqlobject import *
from turbogears.identity.model import somodel

class Report(SQLObject):
title = StringCol()
user = ForeignKey("User")
_SO_class_User = somodel.User

Dan Jacob

unread,
Nov 25, 2005, 7:28:06 AM11/25/05
to TurboGears
Further to what I just said:

This does not work with Catwalk, I get an alert saying "Fail to get
reference to object User" if I click on the Report table.

It seems that the most instinctive way would be to have user =
ForeignKey("turbogears.User") but we'll see how future versions of
SQLObject will resolve this.

Jeff Watkins

unread,
Nov 25, 2005, 8:32:12 AM11/25/05
to turbo...@googlegroups.com
Since this is causing *so* much grief, I'd like to back out the change that moved the identity model objects into their own registry. However, I realise this may not be good for everyone.

So if this will cause you *lots* of grief, please let me know (email directly because I'm distracted by other issues).

Otherwise, I'm going to check a change in that backs this out tomorrow.

“In science it often happens that scientists say, ‘You know that’s a really good argument; my position is mistaken,’ and then they actually change their minds and you never hear that old view from them again. They really do it. It doesn’t happen as often as it should, because scientists are human and change is sometimes painful. But it happens every day. I cannot recall the last time something like that happened in politics or religion.” Carl Sagan, 1987

Reply all
Reply to author
Forward
0 new messages