Flask-Sqlalchemy 3路多对多的关系

时间:2014-01-10 00:41:21

标签: python-2.7 flask flask-sqlalchemy

我正在尝试为事件和事件RSVP创建数据库...

对于每个活动,应该有可能的食物项目供rsvp选择

当用户使用RSVP时,为他们创建的rsvp模型应包含他们目前所选择的食物项目。

这是我到目前为止所做的:

event_meals = db.Table('event_meals',
                       db.Column('meal_id', db.Integer, db.ForeignKey('meal.id')),
                       db.Column('event_id', db.Integer, db.ForeignKey('event.id')))

rsvp_meals = db.Table('rsvp_meals',
                      db.Column('meal_id', db.Integer, db.ForeignKey('meal.id')),
                      db.Column('rsvp_id', db.Integer, db.ForeignKey('rsvp.id')))

class Event(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(256), unique=True)
    date = db.Column(db.String(128))
    photo = db.Column(db.String(256))
    info = db.Column(db.String(1024))
    meals = db.relationship('Meal', secondary='event_meals',
                            backref=db.backref('meals', lazy='dynamic'))

    def __repr__(self):
        return self.title


class Rsvp(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128))
    price = db.Column(db.String(64))
    meals = db.relationship('Meal', secondary='rsvp_meals',
                            backref=db.backref('meals', lazy='dynamic'))

    def __repr__(self):
        return self.name


class Meal(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(128))
    price = db.Column(db.Integer)
    qty = db.Column(db.Integer)

    def __repr__(self):
        return self.title

毫不奇怪,这会产生错误:

sqlalchemy.exc.ArgumentError:在关系'Rsvp.meals'上创建backref'餐点'时出错:该名称的属性存在于mapper'Mapper | Meal | meal'

任何人都可以帮我做这个工作吗?!非常感谢帮助!

1 个答案:

答案 0 :(得分:2)

backref是用于在相关模型上公开多对多关系的名称。在您的情况下,您说EventRsvp模型应该作为meals模型上的属性Meal公开。换句话说,当我有Meal并且我想看看谁有RSVP时,我应该访问meals实例上的Meal属性。但是,您也声明如果我想查看与该膳食相关的Event,我应该访问该膳食的meals属性...这就是SQLAlchemy抛出错误的原因。< / p>

您最有可能的意思是在rsvps上公开eventsMeals

class Event(db.Model):
    # ... snip ...
    meals = db.relationship('Meal', secondary='event_meals',
                            backref=db.backref('events', lazy='dynamic'))

# ... snip ...    

class Rsvp(db.Model):
    # ... snip ...
    meals = db.relationship('Meal', secondary='rsvp_meals',
                            backref=db.backref('rsvps', lazy='dynamic'))

然后,对于任何Meal个实例,您可以查询其EventRSVP s:

for rsvp in Meal.query.get(meal_id).rsvps:
    print rsvp.name

需要注意的关键是SQLAlchemy是一个非常干(不要重复自己)的框架。如果您发现自己必须在同一字段的声明的不同部分之间保持名称同步,那么您可能错过了一种更简单的方法。