I'm trying to setup a basic many-to-many relationship using sqlalchemy and can't pin down what I'm doing wrong. Essentially, I have a table of Users and a table of Offers (basically, something like Groupon). Users can respond to many offers, and offers can be sent to many users. I've been using this section of the sqlalchemy docs but clearly I'm doing something wrong.
Here is the relevant section of my code:
class Offer(db.Model):
__tablename__ = 'offers'
id = Column(Integer, primary_key=True)
title = Column(String)
description = Column(String)
users = association_proxy('user_offers', 'user')
def __init__(self, title, description):
self.title = title
self.description = description
class User(db.Model):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
first_name = Column(String, nullable=False)
last_name = Column(String, nullable=False)
email = Column(String, index=True, unique=True)
def __init__(self, first_name, last_name, email):
self.first_name = first_name
self.last_name = last_name
self.email = email.lower()
class UserOfferResponse(db.Model):
__tablename__ = 'user_offer_responses'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('users.id'))
offer_id = Column(Integer, ForeignKey('offers.id'))
response = Column(String)
created_at = Column(DateTime)
offer = relationship(Offer,
backref=backref("user_offers",
cascade="all, delete-orphan")
)
user = relationship("User")
def __init__(self, offer=None, user=None, response="", created_at=datetime.datetime.now()):
self.response = response
self.offer = offer
self.user = user
self.created_at = created_at
Using the code above, I can create an Offer and a User, but if I try to associate the two (offer.users.append(user)
) I get the following error:
File "/Users/scottmorse/.virtualenvs/WhereItsApp/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 224, in __set__
instance_dict(instance), value, None)
File "/Users/scottmorse/.virtualenvs/WhereItsApp/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 802, in set
value = self.fire_replace_event(state, dict_, value, old, initiator)
File "/Users/scottmorse/.virtualenvs/WhereItsApp/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 824, in fire_replace_event
self._replace_token or self._init_append_or_replace_token())
File "/Users/scottmorse/.virtualenvs/WhereItsApp/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 1153, in emit_backref_from_scalar_set_event
child_impl = child_state.manager[key].impl
KeyError: 'user_offers'
Any help would be appreciated, and thanks for reading.
Found the answer here: KeyError when adding objects to SQLAlchemy association object
Because I was trying to add a user to the offer's list, I needed to either 1) make sure that the User is the first item passed to the UserOfferResponse constructor (because that is how it will be called by the association_proxy, or 2) add an explicit 'creator' parameter to the association_proxy.
I chose option 2, as it allows me to work in "both directions". Thanks for reading!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With