簡體   English   中英

SQLAlchemy “命令式映射”多對多關系

[英]SQLAlchemy "imperative mapping" many to many relationship

我有兩個表,學生和課程。 我正在嘗試使用 SQLAlchemy 命令式映射樣式在這兩個實體之間創建多對多關系,但我找不到任何示例。

下面是我的兩個表:

student_table = Table(
    'student',
    metadata,
    Column('id', Integer, primary_key=True),
    Column('name', String(50)),
    Column('course_id', String(255), ForeignKey('course.id')
)

course_table = Table(
    'course',
    metadata,
    Column('id', Integer, primary_key=True),
    Column('name', String(50)),
    Column('student_id', String(255), ForeignKey('student.id')
)

mapper_registry.map_imperatively(
    Student, 
    student_table, 
    properties (
        'course': relationship (
                Course,
                backref='student'
        )
    )
)

mapper_registry.map_imperatively(
    Course, 
    course_table, 
    properties (
        'course': relationship (
                Student,
                backref='course'
        )
    )
)

@dataclass
class Student:
    id: int 
    name: str 
    course_id: str

@dataclass
class Course:
    id: int 
    name: str 
    student_id: str

這對我不起作用,有人闡明如何使用命令式映射 styles 實現多對多關系嗎?

我嘗試使用命令式 styles 創建多對多關系,但無法實現任何工作示例

您不僅是命令式映射,而且還映射數據類,這意味着您應該使用稍微不同的語法。

然后對於多對多關系,你需要一個關聯表。

將這兩個與您的代碼放在一起,這就是我的建議。

首先映射每個數據類,使用命令表__table__並通過__mapper_args__包括通過secondary表的關系(注意,它是一個用於后期評估的字符串,因為我在數據類之后定義它,如果首先定義你可以直接使用變量)。

然后像文檔中那樣創建關聯表。

from __future__ import annotations

from dataclasses import dataclass, field

from sqlalchemy import (
    Column,
    ForeignKey,
    Integer,
    String,
    Table,
    create_engine,
)
from sqlalchemy.orm import registry, relationship

mapper_registry = registry()


@mapper_registry.mapped
@dataclass
class Student:
    __table__ = Table(
        "student",
        mapper_registry.metadata,
        Column("id", Integer, primary_key=True),
        Column("name", String(50)),
    )

    id: int = field(init=False)
    name: str
    courses: list[Course] = field(default_factory=list)

    __mapper_args__ = {
        "properties": {
            "courses": relationship(
                "Course",
                secondary="course_student_association_table",
                back_populates="students",
            )
        }
    }


@mapper_registry.mapped
@dataclass
class Course:
    __table__ = Table(
        "course",
        mapper_registry.metadata,
        Column("id", Integer, primary_key=True),
        Column("name", String(50)),
    )

    id: int = field(init=False)
    name: str
    students: list[Course] = field(default_factory=list)

    __mapper_args__ = {
        "properties": {
            "students": relationship(
                "Student",
                secondary="course_student_association_table",
                back_populates="courses",
            )
        }
    }


course_student_association_table = Table(
    "course_student_association_table",
    mapper_registry.metadata,
    Column("course_id", ForeignKey("course.id"), primary_key=True),
    Column("student_id", ForeignKey("student.id"), primary_key=True),
)

engine = create_engine("sqlite://", future=True, echo=True)

mapper_registry.metadata.create_all(engine)

這發出

CREATE TABLE student (
        id INTEGER NOT NULL, 
        name VARCHAR(50), 
        PRIMARY KEY (id)
);

CREATE TABLE course (
        id INTEGER NOT NULL, 
        name VARCHAR(50), 
        PRIMARY KEY (id)
);

CREATE TABLE course_student_association_table (
        course_id INTEGER NOT NULL, 
        student_id INTEGER NOT NULL, 
        PRIMARY KEY (course_id, student_id), 
        FOREIGN KEY(course_id) REFERENCES course (id), 
        FOREIGN KEY(student_id) REFERENCES student (id)
);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM