[英]Many to many relationship with a composite key on SQLAlchemy
Let's say I have the following model:假设我有以下模型:
class Molecule(Base):
db = Column(Integer, primary_key=True)
id = Column(Integer, primary_key=True)
data = Column(Integer)
class Atom(Base):
id = Column(Integer, primary_key=True)
weight = Column(Integer)
And I want to establish a many-to-many relationship between Molecule and Atom, what would be the best way to do it?我想在 Molecule 和 Atom 之间建立多对多关系,最好的方法是什么? Notice that the primary key of Molecule is composite .
注意 Molecule 的主键是复合的。
Thanks谢谢
many-to-many association tables should be defined like this:多对多关联表应该这样定义:
molecule2atom = Table(
'molecule2atom',
Base.metadata,
Column('molecule_db', Integer),
Column('molecule_id', Integer),
Column('atom_id', Integer, ForeignKey('atom.id')),
ForeignKeyConstraint(
('molecule_db', 'molecule_id'),
('molecule.db', 'molecule.id') ),
)
And add the relatiohship to one of the models as usual, for example, in Class Atom add:并像往常一样将关系添加到模型之一,例如,在 Class Atom 添加:
molecules = relationship("Molecule", secondary=molecule2atom, backref="atoms")
我更喜欢这里给出的解决方案 - 多对多组合键
If you're using an association table or fully declared table metadata, you can use the primary_key=True
in both columns, as suggested here .如果您使用关联表或完全声明的表元数据,则可以在两列中使用
primary_key=True
,如建议here 。
Association table example:关联表示例:
employee_role = db.Table(
"employee_role",
db.Column("role_id", db.Integer, db.ForeignKey("role.id"), primary_key=True),
db.Column("employee_id", db.Integer, db.ForeignKey("agent.id"), primary_key=True),
)
Metadata example:元数据示例:
# this is using SQLAlchemy
class EmployeeRole(Base):
__tablename__ = "employee_role"
role_id = Column(Integer, primary_key=True)
employee_id = Column(Integer, primary_key=True)
# this is using Flask-SQLAlchemy with factory pattern, db gives you access to all SQLAlchemy stuff
class EmployeeRole(db.Model):
__tablename__ = "employee_role"
role_id = db.Column(db.Integer, primary_key=True)
employee_id = db.Column(db.Integer, primary_key=True)
Alembic migration for it:它的 Alembic 迁移:
op.create_table(
'employee_role',
sa.Column('role_id', sa.Integer(), nullable=False),
sa.Column('employee_id', sa.Integer(), nullable=False),
sa.PrimaryKeyConstraint('role_id', 'employee_id')
)
SQL:查询语句:
CREATE TABLE agent_role (
role_id INTEGER NOT NULL,
employee_id INTEGER NOT NULL,
PRIMARY KEY (role_id, employee_id)
);
In terms of relationship, declare it on one side (this should give you role.employees
or employee.roles
which should return a list
):在关系方面,在一侧声明它(这应该给你
role.employees
或employee.roles
,它应该返回一个list
):
# this is using Flask-SQLAlchemy with factory pattern, db gives you access to all SQLAlchemy stuff
class Employee(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
roles = db.relationship("Role", secondary=employee_role, backref="employee")
Your Role class can be:您的角色类可以是:
# this is using Flask-SQLAlchemy with factory pattern, db gives you access to all SQLAlchemy stuff
class Role(db.Model):
__tablename__ = "role"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(25), nullable=False, unique=True)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.