Понимание результатов запроса отношения SQLAlchemy ForeignKey - PullRequest
0 голосов
/ 01 августа 2020

Я пытаюсь понять, как выходные данные запроса SQLAlchemy могут быть постоянно вложенными, как если бы это был бесконечный объект. (Я уверен, что это неправильный способ называть это)

Сценарий следующий. Я создал отношения «один-ко-многим» между пользователем и их домашними животными.

class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True)
    name = Column(String, unique=True)

    pets = relationship("Pet", back_populates="owner")

class Pet(Base):
    __tablename__ = "pets"
    id = Column(Integer, primary_key=True)
    name = Column(String)
    owner_id = Column(Integer, ForeignKey("users.id"))

    owner = relationship("User", back_populates="pets")

Теперь, когда я запрашиваю пользователя, я также могу запрашивать информацию о домашних животных, как показано ниже:

records = session.query(User).all()

Это возвращает список пользователей со своими домашними животными в воображаемом поле. Теперь, когда я пытаюсь получить доступ к информации о домашних животных, я могу сделать это, обратившись к массиву. Например:

records[0].pets[0].name

В то же время я могу постоянно получать доступ к пользователю снова, а затем снова к количеству домашних животных и пользователю и так далее ...

records[0].pets[0].owner.pets[0].owner.pets[0].....

Этот вопрос возник, когда я изучал graphQL и наткнулся на нечто подобное.

Мой вопрос: как это явление стало возможным в Python? Это бесконечный объект или есть какая-то вещь с круговыми ссылками? Мне очень жаль, что я не смог правильно сформулировать это, так как я не уверен, как называется эта проблема / функция.

Большое спасибо за ваше время и удачного дня.

С Уважением, Джастин

ИЗМЕНИТЬ: Нашел документы, которые это объясняют! https://docs.sqlalchemy.org/en/13/orm/self_referential.html

1 Ответ

1 голос
/ 01 августа 2020

Я вижу, что рассматриваемый запрос может показаться какой-то бесконечной цепочкой объектов, но, как вы сами отметили, это, возможно, лучше всего понимать как форму круговой ссылки.

Более конкретно, у каждого домашнего питомца может быть один владелец. В свою очередь, у каждого хозяина может быть несколько питомцев. Запрос

records[0].pets[0].owner.pets[0].owner.pets[0].....

означает, что вы получаете владельца первого питомца, затем домашних животных этого владельца, затем владельца первого питомца и так далее.

Таким образом, мы можем установить sh следующую рекуррентную связь:

records[0].pets[0] = records[0].pets[0].owner.pets[0]

Таким образом, бесконечная цепочка под капотом не является действительно бесконечной; запрос просто ходит по кругу. @Klaus D. уже привел отличную аналогию входной двери. Я мог бы добавить сюда еще одну потенциально интуитивно понятную ссылку в CS, которая представляет собой древовидную структуру данных: вы переходите от одного листа к его родительскому узлу, а затем обратно к листу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...