使用检查确定关系类型

时间:2019-06-29 14:47:25

标签: python sqlalchemy

我需要追溯确定一种关系类型是否为一对一。

在我的用例中,第三方开发人员可以将具有一对一关系的新表(例如Manager和/或Worker)添加回主表(此处称为Person)。他们可能还会添加一对多的新表。我需要忽略这些。

以下代码段:

from sqlalchemy import * 
from sqlalchemy.orm import *
from sqlalchemy.ext.automap import automap_base

e = create_engine("sqlite://", echo=True)
e.execute(""" 
     create table person (id integer primary key) 
""") 
e.execute(""" 
     create table manager (id integer primary key, person_id integer,
     FOREIGN KEY(person_id) REFERENCES person(id)) 
""") 
e.execute(""" 
     create table worker (id integer primary key, person_id integer,
     FOREIGN KEY(person_id) REFERENCES person(id)) 
""") 

Base = automap_base() 

class Person(Base): 
    __tablename__ = 'person' 
    id = Column(Integer, primary_key=True) 

class Manager(Base): 
    __tablename__ = 'manager' 
    id = Column(Integer, primary_key=True)
    person_id = Column(Integer, ForeignKey('person.id'))
    person = relationship("Person", uselist=False)

class Worker(Base): 
    __tablename__ = 'worker' 
    id = Column(Integer, primary_key=True)
    person_id = Column(Integer, ForeignKey('person.id'))
    person = relationship("Person", uselist=False)

class WorkerUnion(Base):
    __tablename__ = 'worker_union' 
    id = Column(Integer, primary_key=True)
    person_id = Column(Integer, ForeignKey('person.id'))
    person = relationship("Person", uselist=True)    

Base.prepare(e) 

for r in inspect(Person).relationships:
    print(f"{r.target.name}, {r.uselist}, {r.collection_class}")

输出:

manager, True, <class 'list'>
worker, True, <class 'list'>
worker_union, True, <class 'list'>

当我为经理/工人关系指定uselist = False时,我感到困惑。

我显然缺少一些东西,有没有一种方法可以使用检查来确定每个班级的关系性质?

2 个答案:

答案 0 :(得分:1)

我使用以下代码来确定关系类型。我还添加了确定是多对多还是多对一关系的方法,因为我经常必须根据该条件执行。以“人物”为例:

from sqlalchemy.orm.interfaces import MANYTOMANY, MANYTOONE
from sqlalchemy import inspect

for relationship in inspect(Person).relationships:
  direction = relationship.direction
  print(direction)

  if direction == MANYTOMANY:
    # execute some code
  elif direction == MANYTOONE:
    # execute some other code

答案 1 :(得分:0)

感谢有用的建议答案和评论。

看每个发现的实体的关系似乎是每个关系中的窍门。例如:

for r in inspect(Person).relationships:
    for s in inspect(r.entity.entity).relationships:
        if s.entity.entity == Person:
            print(f"{r.target.name}, {s.uselist}, {s.collection_class}")