5

次のモデルがあるとします。

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)

そして、Molecule と Atom の間に多対多の関係を確立したいのですが、それを行う最善の方法は何でしょうか? Molecule の主キーcompositeであることに注意してください。

ありがとう

4

3 に答える 3

10

多対多関連テーブルは、次のように定義する必要があります。

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')  ),
)

そして、通常どおりモデルの 1 つにリレーションシップを追加します。たとえば、Class Atom に次のように追加します。

molecules = relationship("Molecule", secondary=molecule2atom, backref="atoms")
于 2013-03-07T10:14:40.310 に答える
0

関連付けテーブルまたは完全に宣言されたテーブル メタデータを使用している場合は、ここでprimary_key=True提案されているように、両方の列で を使用できます。

関連テーブルの例:

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),
)

メタデータの例:

# 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 移行:

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)
);

関係に関しては、片側で宣言します(これにより、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")

Role クラスは次のようになります。

# 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)
于 2021-07-07T13:12:30.960 に答える