如何使用Flask-sqlalchemy与额外数据创建多对多关联?

时间:2014-10-14 13:40:15

标签: python flask sqlalchemy flask-sqlalchemy

我需要使用flask-sqlalchemy将两个模型员工技能与额外数据相关联。

例如, user1 可以效率技能1 效率100%,技能2 效率80%。

所以,我制作了3个模型:

class Employee(db.Model):
    __tablename__ = 'employees'

    id = db.Column(db.Integer, primary_key=True)
    login = db.Column(db.String(64), index=True, unique=True, nullable=False)

    skills = db.relationship('Skill', secondary='employee_skills',
                             backref=db.backref('employees', lazy='dynamic'))

    def __repr__(self):
        return '<Employee %r, Skills: %r>' % (self.login, self.skills)


class Skill(db.Model):
    __tablename__ = 'skills'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), nullable=False, unique=True)

    def __repr__(self):
        return '<Skill %r>' % self.name


class EmployeeSkill(db.Model):
    __tablename__ = 'employee_skills'

    employee_id = db.Column(db.Integer, db.ForeignKey('employees.id'), primary_key=True)
    skill_id = db.Column(db.Integer, db.ForeignKey('skills.id'), primary_key=True)
    efficiency = db.Column(db.Float)

    skills_efficiency = db.relationship('Skill', backref=db.backref('employee_efficiency', lazy='dynamic'))

    def __repr__(self):
        return '<Engineer %r, skill %r, efficiency %r>' % (
            self.employee_id, self.skill_id, self.efficiency)

之后我尝试访问此关联:

>>> from app import db, models      
>>> emp_=models.Employee.query.all()
>>> emp_[0]
<Employee u'user1', Skills: [<Skill u'skill1'>, <Skill u'skill2'>]>
>>> emp_[0].skills
[<Skill u'skill1'>, <Skill u'skill2'>]
>>> emp_[0].skills[0]
<Skill u'skill1'>
>>> emp_[0].skills[0].employee_efficiency
<sqlalchemy.orm.dynamic.AppenderBaseQuery object at 0x0000000003A68FD0>
>>> emp_[0].skills[0].employee_efficiency[0]
<Engineer 1, skill 1, efficiency u'1'>

我想要的是将员工实例表示为

<Employee u'user1', Skills: <u'skill1', efficiency: '1'>, <u'skill2', efficiency: '0.8'>>

但我不明白:我是否以错误的方式使用db.relationship?或者我是否需要使用 repr 方法?

提前致谢

2 个答案:

答案 0 :(得分:3)

如果在关联表中需要额外的列,则需要使用association object模式而不是secondary属性。这种模式基本上在于将多对多关系分解为两个一对多关系。

在您的情况下,您将创建从EmployeeEmployeeSkills的一对多关系,并且您将保持EmployeeSkillsSkill之间已有的多对一关系secondary

使用{{1}}属性时,SQLAlchemy会自动管理关联表。当您使用关联对象模式时,您必须自己管理关联表,这使您可以设置或查询额外的列。

答案 1 :(得分:-1)

是的,您可以更改repr方法:

class Skill(db.Model):
    __tablename__ = 'skills'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), nullable=False, unique=True)

    def __repr__(self):
        return '<Skill %r, efficiency: %r>' % (self.name, self.employee_efficiency[0].efficiency)

你已经有了反射,所以请使用它。