Thank you again, Connor. I'll give it a try on Monday and I'll let you
know the results.

I kind of suspected that having the classes defined in two different
places was making the whole thing go nuts, but that's the way I found
it (and I was trying to keep it consistent with what was there) but I
don't think that under any concept re-writing code is a good idea so
I'll try to change it.

Thank you for the very well explained and detailed reply.

2010/10/29 Conor <conor.edward.da...@gmail.com>:
> On 10/29/2010 05:31 PM, Hector Blanco wrote:
>
> Hello, group!
>
> I am still dealing with the relationship I asked before
> (http://groups.google.com/group/sqlalchemy/browse_thread/thread/c1d46daf35116999).
>
> To tell the truth, I'm not even sure if this is a question I should
> ask in the SqlAlchemy forum because I'm also dealing with Megrok.rdb
> (http://pypi.python.org/pypi/megrok.rdb) and I don't know if that's
> what is causing the problem, but I'm pretty lost...  As I explained in
> my other question, I think the rdb.Model thing that appears in the
> classes is just a tool to create the mapper "class <--> table" in a
> slightly more transparent way for the programmer. That's why I thought
> I may get some help here.
>
> In this message, I have simplified the code (compared to my former
> question) to make it clearer, but well... The fact is that now I'm
> getting a problem with a simple 1:1 relationship (if I can fix it, I
> will be able to move to the more complicated stuff as I detailed in
> the former question)
>
> I am getting this error:
> Foreign key assocated with column 'children_table.id' could not find
> table 'parents_table' with which to generate a foreign key to target
> column 'id'
>
> I have a file, called Tables.py where all the classes and auxiliary
> (or intermediate) tables that I'm going to use in my application are
> defined:
>
> Tables.py >>
>
> class Parent(rdb.Model):
>       rdb.metadata(metadata)
>       rdb.tablename("parents_table")
>
>       id = Column("id", Integer, primary_key=True)
>       _whateverField= Column("whatever_field", String(16)) #Irrelevant
>
>       child1 = relationship("Child", uselist=False)
>
> class Child(rdb.Model):
>       rdb.metadata(metadata)
>       rdb.tablename("children_table")
>       id = Column("id", Integer, ForeignKey(Parent.id), primary_key = True)
>       type = Column("type", String(2)) #Irrelevant (for this example)
>
> The target of a ForeignKey should be a string, e.g.:
>
> ForeignKey("parents_table.id")
>
>      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> And then I have two different Python .py files (Parent.py and
> Child.py) where the methods that manage said classes are implemented.
> In those files, the static area of each class is copied from Tables.py
> with some changes in the quotes (where I can use the object itself, I
> use it):
>
> Parent.py >>
>
> from child import Child
> metadata = rdb.MetaData()
>
> class Parent(rdb.Model):
>       rdb.metadata(metadata)
>       rdb.tablename("parents_table")
>
>       id = Column("id", Integer, primary_key=True)
>       _whateverField= Column("whatever_field", String(16)) #Irrelevant
>
>       child1 = relationship(Child, uselist=False) #No quotation marks on this
> Child
>      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> And
>
> Child.py > >
> metadata = rdb.MetaData()
>
> class Child(rdb.Model):
>       rdb.metadata(metadata)
>       rdb.tablename("children_table")
>       id = Column("id", Integer, ForeignKey("parent_table.id"), primary_key =
> True)
>       type = Column("type", String(2)) #Irrelevant (for this example)
>
> These class definitions should be merged with those in Tables.py. You should
> only have one "class Parent" statement and one "class Child" statement. You
> may be confusing this with the non-declarative class setup, where you define
> the table first, class 2nd, and mapper 3rd. It looks like rdb uses the
> declarative approach, where the table and mapper are defined as part of the
> class in one step.
>
> Also, it is a good idea to make the first argument to relationship() a
> string, as it lets you avoid worrying about which order classes are defined.
> Example:
>
> # This works even if Child hasn't been defined yet.
> child1 = relationship("Child", uselist=False)
>
>      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> When I try to use these classes, I get:
> Foreign key assocated with column 'children_table.id' could not find
> table 'parents_table' with which to generate a foreign key to target
> column 'id'
>
> This is probably due to the foreign key issue above.
>
> But if I take a look to the tables with a MySQL Query Browser, the
> table "parents_table" is there, happily and properly created.
>
> In some other places, I have had similar problems, but I've been able
> to fix them by delaying the imports. I had been able to (kind of)
> import the Parent type in the Child file so I can use the Parent
> object directly. It would be a little bit as if in this case I was
> able to do:
>
> from parent import Parent
> [ . . . ]
>
> class Child(rdb.Model):
>       [ . . . ]
>       id = Column("id", Integer, ForeignKey(Parent.id), primary_key = True)
>
> and that usually fixed the problem but in this specific case, I can't
> really do that: In the Parent file I need to import the Child and that
> gives a very, very nasty circular dependency problem.
>
> Is there a way to tell the Child.py file something like "Hey, dude...
> Here's the parent_table that you need!" ?  (Well... In a more Pythonic
> way, of course... I don't think 'dude'is a reserved keywork in Python,
> or an SqlAlchemy type). I don't know, something like:
>
> from whatever.repository.of.tables import parent_table
>
>          so I can, without quotes, use:
>
> id = Column("id", Integer, ForeignKey(parent_table.id), primary_key = True)
>
> (I guess that may work)
>
> Thank you all.
>
> In SQLAlchemy you get around circular dependencies by:
>
> Using strings as the target of ForeignKey()
> Using class name strings as the target of a relation (declarative only)
> Using strings or callables as primaryjoin/secondaryjoin arguments in a
> relationship()
>
> -Conor
>
> --
> 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.
>

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

Reply via email to