many-to-many - sqlalchemy:以多对多关系保留关联表中的列值

标签 many-to-many sqlalchemy

假设我有一个项目表和一个任务表。一个项目可能有很多任务,一个任务可能分配给多个项目。我有一个关联表 project_task,它有项目和任务之间的映射,还有一个额外的 rate 列,用于记录特定项目的任务率。

表:项目

  • 项目编号
  • 姓名
  • 描述

表:任务

  • 任务
  • 姓名
  • 描述
  • 利率 <- 违约率

表:项目_任务

  • 项目编号
  • 任务
  • 费率<- 项目特定费率

我如何在 Sqlalchemy 中映射这种关系?我的目标是 project.tasks 应该给我一个与项目关联的任务对象列表,其中 task.rate 设置为 project_task 表中记录的速率。

非常感谢!

最佳答案

在映射中加入一个表:

import sqlalchemy

from sqlalchemy import Column
from sqlalchemy import Integer
from sqlalchemy import DECIMAL
from sqlalchemy import Unicode
from sqlalchemy import Text
from sqlalchemy import ForeignKey

from sqlalchemy.sql import join

from sqlalchemy.orm import relation
from sqlalchemy.orm import column_property
from sqlalchemy.orm import create_session

from sqlalchemy.ext.declarative import declarative_base

engine = sqlalchemy.create_engine('sqlite:///stackoverflow_6144557.db', echo = True)

Base = declarative_base(bind=engine)

class ProjectTask(Base):
    __tablename__ = 'project_task'

    projectid = Column(Integer, ForeignKey('project.projectid'), primary_key = True)
    taskid = Column(Integer, ForeignKey('task.taskid'), primary_key = True)
    project_rate = Column('rate', DECIMAL(12, 4))

class Task(Base):
    __tablename__ = 'task'

    taskid = Column(Integer, primary_key = True)
    name = Column(Unicode(255))
    description = Column(Text)
    rate = Column(DECIMAL(12, 4))

class Project(Base):
    __tablename__ = 'project'

    projectid = Column(Integer, primary_key = True)
    name = Column(Unicode(255))
    description = Column(Text)
    tasks = relation("ExtendedProjectTask", backref = "project", lazy = 'joined')

class ExtendedProjectTask(Base):
    __table__ = join(ProjectTask.__table__, Task.__table__)

    projectid = column_property(ProjectTask.projectid)
    taskid = column_property(Task.taskid, ProjectTask.taskid)
    name = column_property(Task.name)
    description = column_property(Task.description)
    task_rate = column_property(Task.rate)
    project_rate = column_property(ProjectTask.project_rate)

    @property
    def rate(self):
        if self.project_rate is None:
            return self.task_rate
        else:
            return self.project_rate

if __name__ == '__main__':
    Base.metadata.create_all(engine)
    session = create_session(engine)
    for project in session.query(Project).all():
        print "\n%r, %r, %r" % (project.projectid, project.name, project.description)
        for task in project.tasks:
            print "\t%r, %r, %r, %r" % (task.taskid, task.name, task.description, task.rate)

关于many-to-many - sqlalchemy:以多对多关系保留关联表中的列值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6144557/

相关文章:

ef-code-first - 多对多MVC 5模型代码首先连接表

postgresql - 在 Postgres/SQLAlchemy 上设置 application_name

sqlalchemy - 使用 Jupyter SQL Magic 时如何关闭连接?

python - 使用 python、sqlalchemy 和 psycopg2 创建 PostgreSQL 数据库时出错

c# - Entity Framework 4.1 Code First 创建多对多关系的方法

php - Laravel 多对多加载相关模型与计数

ruby-on-rails - Rails 有很多通过

python - 如何删除 sqlalchemy 列上的自动更新?

python - 过滤前将函数应用于列