views:

67

answers:

2

Hello,

I'm trying to link one table to itself. I have media groups which can contain more media group. I created a relation many to many:

media_group_groups = Table(
            "media_group_groups",
            metadata,
            Column("groupA_id", Integer, ForeignKey("media_groups.id")),
            Column("groupB_id", Integer, ForeignKey("media_groups.id"))
        )

class MediaGroup(rdb.Model):
    """Represents MediaGroup class. Conteins channels and other media groups"""
    rdb.metadata(metadata)
    rdb.tablename("media_groups")

    id = Column("id", Integer, primary_key=True)
    title = Column("title", String(100))
    parents = Column("parents", String(512))

    channels = relationship(Channel, secondary=media_group_channels, order_by=Channel.titleView, backref="media_groups")
    mediaGroup = relationship("MediaGroup", secondary=media_group_groups, order_by="MediaGroup.title", backref="media_groups")

I got this error:

"ArgumentError: Could not determine join condition between parent/child tables on relationship MediaGroup.mediaGroup. Specify a 'primaryjoin' expression. If this is a many-to-many relationship, 'secondaryjoin' is needed as well."

When I create the tables I don't get any error, it's just when I add any element to it. Any idea???

Thanks in advance!

A: 

I could be wrong, but I don't think you can link a table to itself many-to-many, can you?

You'd need to store the links in your records, and those would potentially need to be able to link to every other row in the table, no? Would seem that your columns would need to expand as fast as your records in that case.

What about a separate table that just contains your relationship?

tbl_links (id, primaryMediaGroupID, linkedMediaGroupID)
John at CashCommons
+1  A: 

SQLAlchemy can't figure out which columns in your link table to join on. Try this for the relationship:

mediaGroup = relationship("MediaGroup",
        secondary=media_group_groups,
        order_by="MediaGroup.title",
        backref=backref('media_groups', 
                        secondary="media_media_groups",
                        primaryjoin= id == "groupB_id",
                        secondaryjoin = id == "groupA_id",
                        foreignkeys = ["groupA_id", "groupB_id"] ),  
        primaryjoin = id == "groupA_id",
        secondaryjoin = id == "groupB_id")

This may need some adjustment -- if it doesn't work, try with the join column names being like "media_media_groups.groupA_id" throughout.

Walter Mundt
I tried that, but I got a different error:"ArgumentError: Could not determine relationship direction for primaryjoin condition 'media_groups.id = :id_1', on relationship MediaGroup.mediaGroup. Do the columns in 'foreign_keys' represent only the 'foreign' columns in this join condition ?"I'm trying to solve it, but if you have something in mind, please let me know.Thanks!
bribon
Looks like an issue with the backref. Adjusting my answer.
Walter Mundt
Also note that the names are a bit confusing here. `MediaGroup.mediaGroup` is a list of the `groupA` to `groupB` links, while `MediaGroup.media_groups` is a list of the `groupB` to `groupA` links. If you really need the backref, I'd name them something liked `subgroups` and `supergroups` or whatever makes sense for your model.
Walter Mundt
Yes, I was wrong with the names, I fixed it. I tried the same as you wrote down and I didn't work either. I got the same error. This is what I tried:mediaGroups = relationship("MediaGroup", secondary=media_group_groups, order_by="MediaGroup.title", backref="media_groups", primaryjoin = id == "media_group_groups.groupA_id", secondaryjoin = id == "media_group_groups.groupB_id", foreign_keys=["media_group_groups.groupA_id", "media_group_groups.groupB_id"])Any idea?Thanks for helping me out!
bribon
What you tried is still just a string for the `backref`. When you specify the `primaryjoin` and `secondaryjoin`, you need to turn that into a `backref(...)` constructor specifying how the reverse relationship ought to work, as in my code above.
Walter Mundt
Yeah, I tried that. I have another problem when I make this relation. I got this error: "Could not determine relationship direction for primaryjoin condition 'users.id = user_channels.user_id', on relationship User.channels. Do the columns in 'foreign_keys' represent only the 'foreign' columns in this join condition ?". This error came up from another table and all the tables are working properly without this relation. Almost are the tables are related to each other. Maybe, this relation affects the rest of them in some way. Any idea of How I can solve this problem?
bribon
Looks like the backref for `channels` is also set to `media_groups`, which is causing a conflict. It should probably be called something else.
Walter Mundt