TG2 SqlAlchemy importing models within other models dependency problems

38 views
Skip to first unread message

robneville73

unread,
Mar 13, 2009, 7:05:09 AM3/13/09
to TurboGears
how are people solving this problem? I apologize in advance for the
complex question but without pasting a crap-load of code, I don't know
how to ask it simply.

I have an existing DB that I'm mapping, so as I understand it,
declarative use of SA is not an option.

I have a model called Customer and a model called Order. Order is a
child of Customer (1 Customer : N Order).

I have classmethods in Order that access and reference Customer. So in
the definition of Order I have:
from customer import Customer

now, I need to define a relation in the mapper for Customer. Houston,
we have a problem....

To do that, I need to pass the relation function Order as the first
argument. How do I reference Order?

The problem is that you get a circular import problem I think, because
if I add...
from order import Order
to the definition of Customer, then I get an import error. However, if
I remove the "from customer import Customer" statement from Order,
then it works, but I then I can't do what I need to do.

OK, maybe this is a short way of saying it:
How do I reference methods from other models inside of a model without
creating this import dependency issue?

Christoph Zwerschke

unread,
Mar 13, 2009, 8:54:32 AM3/13/09
to turbo...@googlegroups.com
robneville73 schrieb:

> I have a model called Customer and a model called Order. Order is a
> child of Customer (1 Customer : N Order).

Just as an aside, I would not call a single class a "model". The model
is the whole collection of your database objects and their relations.

> OK, maybe this is a short way of saying it:
> How do I reference methods from other models inside of a model without
> creating this import dependency issue?

I recommend defining related model classes inside the same module.

Also note that SQLAlchemy allows you to pass as-yet undefined objects as
strings.

Or, you can add attribute later, after you declared both classes (e.g.
in __init__.py, after you imported all model classes).

-- Christoph

Robert Neville

unread,
Mar 13, 2009, 9:24:45 AM3/13/09
to turbo...@googlegroups.com
Yeah, I suppose that's the obvious solution (put them in the same file).

I tried passing a string to relation and it complained that it wasn't expecting a string. I saw elsewhere on these posts that someone had said that SA worked that way, but either I'm not doing it right or it really doesn't work that way...maybe it's a bug I don't know.
--
Rob Neville
http://www.robneville.net

http://www.linkedin.com/in/robneville

Ben Sizer

unread,
Mar 13, 2009, 10:31:14 AM3/13/09
to TurboGears
On Mar 13, 1:24 pm, Robert Neville <robertnevill...@gmail.com> wrote:
> I tried passing a string to relation and it complained that it wasn't
> expecting a string. I saw elsewhere on these posts that someone had said
> that SA worked that way, but either I'm not doing it right or it really
> doesn't work that way...maybe it's a bug I don't know.

You can pass a string if you're using the Declarative syntax, because
otherwise you wouldn't be able to declare these circular dependencies.
With the separate mapper, you can declare the circular dependencies
ok, by putting the mapper after the classes.

Another solution, if you didn't want to put the model classes in the
same file, might be to use a 3rd file to break the cycle. The mapper
could go in there, perhaps. It's hard to imagine the exact problem
without seeing the code but in general adding a 3rd file to split the
dependency is usually possible.

--
Ben Sizer

Christoph Zwerschke

unread,
Mar 13, 2009, 10:40:18 AM3/13/09
to turbo...@googlegroups.com
Robert Neville schrieb:

> I tried passing a string to relation and it complained that it wasn't
> expecting a string. I saw elsewhere on these posts that someone had said
> that SA worked that way, but either I'm not doing it right or it really
> doesn't work that way...maybe it's a bug I don't know.

In case of doubt, I recommend asking on the SA mailing list. There you
will get qualified answers to any SA question very quickly.

-- Christoph

Antoine Pitrou

unread,
Mar 13, 2009, 11:08:25 AM3/13/09
to TurboGears
On Mar 13, 12:05 pm, robneville73 <robertnevill...@gmail.com> wrote:
>
> I have classmethods in Order that access and reference Customer. So in
> the definition of Order I have:
> from customer import Customer

Simply move that import inside the methods themselves and it will
remove the circularity.

Diez B. Roggisch

unread,
Mar 13, 2009, 11:23:16 AM3/13/09
to turbo...@googlegroups.com
Christoph Zwerschke schrieb:

> robneville73 schrieb:
>> I have a model called Customer and a model called Order. Order is a
>> child of Customer (1 Customer : N Order).
>
> Just as an aside, I would not call a single class a "model". The model
> is the whole collection of your database objects and their relations.
>
>> OK, maybe this is a short way of saying it:
>> How do I reference methods from other models inside of a model without
>> creating this import dependency issue?
>
> I recommend defining related model classes inside the same module

That's not working.


class Foo(object):

some_attribute = Bar() # bails out


class Bar(object):
other_attribute = Foo()


Define them after both classes are known (which arguably is easier in
one module of course), or use Strings - at least Elixir allows that.


class Foo(Entity):
bars = OneToMany("Bar")


class Bar(Entity):
foo = ManyToOne("Foo")

Diez

Robert Neville

unread,
Mar 13, 2009, 1:04:32 PM3/13/09
to turbo...@googlegroups.com
I tried moving the import inside the methods and it still didn't work. I've been resistant to using the declarative syntax or elixr because I feel like too much magic is happening, but I could be wrong, it's just an impression and I have to admit I haven't really rolled up my sleeves and dug into either yet. I like the feeling that I can control and customize the mapping of the class to the db table.

Plus, I'm under the (possibly mistaken) impression that I can't map to legacy database tables using either declarative or elixr...am I wrong about that?

I think I'll just end up sticking them in the same file but there's something that just feels wrong about that to me, but it's really just a style issue I guess.
Reply all
Reply to author
Forward
0 new messages