Sqlalchemy -Beziehung durch einen anderen (deklarativ)
-
26-09-2019 - |
Frage
Ist jemand mit ActivereCords "Has_Many: Through" -Belationen für Modelle vertraut? Ich bin nicht wirklich ein Rails -Typ, aber das ist im Grunde das, was ich versuche zu tun.
Als erfundenes Beispiel berücksichtigen Sie Projekte, Programmierer und Aufgaben:
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Column, ForeignKey
from sqlalchemy.types import Integer, String, Text
from sqlalchemy.orm import relation
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Assignment(Base):
__tablename__ = 'assignment'
id = Column(Integer, primary_key=True)
description = Column(Text)
programmer_id = Column(Integer, ForeignKey('programmer.id'))
project_id = Column(Integer, ForeignKey('project.id'))
def __init__(self, description=description):
self.description = description
def __repr__(self):
return '<Assignment("%s")>' % self.description
class Programmer(Base):
__tablename__ = 'programmer'
id = Column(Integer, primary_key=True)
name = Column(String(64))
assignments = relation("Assignment", backref='programmer')
def __init__(self, name=name):
self.name = name
def __repr__(self):
return '<Programmer("%s")>' % self.name
class Project(Base):
__tablename__ = 'project'
id = Column(Integer, primary_key=True)
name = Column(String(64))
description = Column(Text)
assignments = relation("Assignment", backref='project')
def __init__(self, name=name, description=description):
self.name = name
self.description = description
def __repr__(self):
return '<Project("%s", "%s...")>' % (self.name, self.description[:10])
engine = create_engine('sqlite://')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
Projekte haben viele Aufgaben.
Programmierer haben viele Aufgaben. (Untertreibung?)
Zumindest in meinem Büro haben Programmierer auch viele Projekte - ich möchte, dass diese Beziehung durch die dem Programmierer zugewiesenen Aufgaben abgeleitet wird.
Ich möchte, dass das Programmierermodell ein Attribut "Projekte" hat, das eine Liste von Projekten zurückgibt, die dem Programmierer über das Zuordnungsmodell zugeordnet sind.
me = session.query(Programmer).filter_by(name='clay').one()
projects = session.query(Project).\
join(Project.assignments).\
join(Assignment.programmer).\
filter(Programmer.id==me.id).all()
Wie kann ich diese Beziehung klar beschreiben und einfach die deklarative Syntax von SQLalchemy verwenden?
Vielen Dank!
Lösung
Es gibt zwei Möglichkeiten, wie ich sehe:
Eine Beziehung definieren
Programmer.projects
mitsecondary='assignment'
.Ich definiere
Assignment.project
als Beziehung undProgrammer.projects
wieassociation_proxy('assignments', 'project')
(Wahrscheinlich möchten Sie auch einen Schöpfer definieren). Sehen Vereinfachung der Assoziationsobjektbeziehungen Kapitel für weitere Informationen.