Определить тип отношений с помощью проверки - PullRequest
0 голосов
/ 29 июня 2019

Мне нужно определить, является ли тип отношения один к одному ретроспективно.

В моем случае использования сторонний разработчик может добавлять новые таблицы (например, «Менеджер» и / или «Рабочий») с отношением «один к одному» обратно в основную таблицу (здесь она называется «Персона»). Они могут также добавить новые таблицы, которые один-ко-многим; Я должен игнорировать их.

Следующий фрагмент:

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 для отношений менеджер / работник.

Я явно что-то упускаю, есть ли способ определить характер отношений для каждого класса с помощью inspect?

Ответы [ 2 ]

1 голос
/ 29 июня 2019

Я использую следующий код для определения типа отношения. Я также добавил способ, которым я определяю, является ли это отношением «многие ко многим» или «многие к одному», потому что мне часто приходится выполнять на основе этого условия. Используя пример Person:

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
0 голосов
/ 30 июня 2019

Спасибо за полезные предложенные ответы и комментарии.

Кажется, уловка заключается в том, чтобы в каждом отношении смотреть на отношения каждого обнаруженного объекта. Например:

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}")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...