Reputation: 20246
I have something similar to this:
class Item(Base, DBBase):
__tablename__ = 'item'
id = Column(Integer, primary_key = True)
name = Column(String), nullable = True)
comments = relationship('ItemComment')
class ItemComment(Base, DBBase):
__tablename__ = 'itemcomments'
item_id = Column(Integer, ForeignKey('item.id'), nullable = False, primary_key=True)
comment = Column(String), nullable = False, primary_key=True)
I am wondering if it's possible to have the relationship map directly to the string so I can avoid handling ItemComment objects directly in the code. For example adding a new comment like this: item.comments.append("hello")
or directly iterate over the string comments using for comment in item.comments:
. I assume it could work with a @property, but is there a way to setup the relationship to handle it transparently ?
Upvotes: 1
Views: 92
Reputation: 76962
Exactly what Association Proxy
extension is doing. In your case it would mean having the model like below:
class Item(Base, DBBase):
__tablename__ = 'item'
id = Column(Integer, primary_key = True)
name = Column(String, nullable = True)
comments = relationship('ItemComment')
comms = association_proxy('comments', 'comment',
creator=lambda comment: ItemComment(comment=comment),
)
class ItemComment(Base, DBBase):
__tablename__ = 'itemcomments'
item_id = Column(Integer, ForeignKey('item.id'), nullable = False, primary_key=True)
comment = Column(String, nullable = False, primary_key=True)
def __init__(self, comment):
self.comment = comment
and you can use it exactly like you wish:
my_item.comms.append("super")
print "All Comments: ", my_item.comms
One additional comment: you either need to specify the creator
parameter (like in the code above) or else it is expected that you have a one-parameter constructor on ItemComment
(like above), but one of the two suffice. I usually prefer explicit creation via creator
parameter.
Also, you might want to rename comments
to _comments
and comms
to comments
.
Upvotes: 2