使用派生字段更新多对多关联表

时间:2015-06-18 03:46:34

标签: python flask sqlalchemy many-to-many flask-sqlalchemy

我正在使用Flask,Flask-SQLalchemy和Flask-Restful编写RESTful API。我有联系人和类别的模型,以及一个帮助表,用于映射它们之间的多对多关系。

contactgrouping = db.Table('CONTACT_GROUPING',
    db.Column('catid', db.Integer, db.ForeignKey('CATEGORY.catid')),
    db.Column('contactid', db.Integer, db.ForeignKey('CONTACT.contactid')),
    db.Column('clientid', db.Integer, db.ForeignKey('CLIENT.clientid')),
)

class Contact(db.Model):

    __tablename__ = 'CONTACT'
    contactid = db.Column(db.Integer, primary_key=True)
    clientid = db.Column(db.Integer, db.ForeignKey('CLIENT.clientid'))
    firstname = db.Column(db.String(50))
    lastname = db.Column(db.String(50))
    categories = db.relationship('Category',secondary = contactgrouping, backref='contact', lazy='dynamic')

class Category(db.Model):

    __tablename__ = 'CATEGORY'
    catid = db.Column(db.Integer, primary_key=True)
    clientid = db.Column(db.Integer, db.ForeignKey('CLIENT.clientid'))
    catname = db.Column(db.String(50))

我正在使用ORM更新给定联系人的类别,这很有效。复杂的是映射表具有非规范化字段clientid,它与Contact表中的clientid相同。当ORM更新联系人的类别分配时,我需要填充此字段,但只插入contactidcatid列。

示例:

            category = Category.query.get(catid).first()
            if (category is not None):
                contact.categories.append(category)

这会生成SQL:

INSERT INTO `CONTACT_GROUPING` (catid, contactid) VALUES (%s, %s)

当我真的需要它时:

INSERT INTO `CONTACT_GROUPING` (catid, contactid, clientid) VALUES (%s, %s, %s)

如何定义Contact和Category之间的关系,以便通过ORM填充此派生字段?

1 个答案:

答案 0 :(得分:0)

我在https://twitter.com/140am上得到了一些帮助。我需要将class Category(db.Model): resource_fields = { 'id': fields.Integer(attribute='catid'), 'name': fields.String(attribute='catname') } __tablename__ = 'CATEGORY' catid = db.Column(db.Integer, primary_key=True) clientid = db.Column(db.Integer, db.ForeignKey('CLIENT.clientid')) catname = db.Column(db.String(50)) def __repr__(self): return '<Category %r>' % (self.catname) class ContactGrouping(db.Model): resource_fields = { 'id': fields.Integer(attribute='catid'), 'name': fields.String(attribute='category.catname'), } __tablename__ = 'CONTACT_GROUPING' __table_args__ = ( PrimaryKeyConstraint('catid', 'contactid', 'clientid'), ) catid = db.Column(db.Integer, db.ForeignKey('CATEGORY.catid')) contactid = db.Column(db.Integer, db.ForeignKey('CONTACT.contactid')) clientid= db.Column(db.Integer, db.ForeignKey('CONTACT.clientid')) category = db.relationship('Category') def __repr__(self): return '<ContactGrouping %r %r>' % (self.catid, self.contactid) class Contact(db.Model): resource_fields = { 'id': fields.Integer(attribute='contactid'), 'firstname': fields.String, 'lastname': fields.String, 'categories': fields.List(fields.Nested(ContactGrouping.resource_fields)) } __tablename__ = 'CONTACT' contactid = db.Column(db.Integer, primary_key=True) clientid = db.Column(db.Integer, db.ForeignKey('CLIENT.clientid')) firstname = db.Column(db.String(50)) lastname = db.Column(db.String(50)) categories = db.relationship('ContactGrouping', backref='contact', lazy='dynamic', foreign_keys='ContactGrouping.contactid') def __repr__(self): return '<Contact %r %r>' % (self.firstname, self.lastname) 表示为模型而不是表,以便我可以直接使用关系和访问字段。

        category = Category.query.get(catid).first()
        contactgrouping = ContactGrouping(contactid=id, catid=category.catid, clientid = contact.clientid)
        if (contactgrouping is not None):
            contact.categories.append(contactgrouping)

并在视图中使用它:

{{1}}