Подтвердить что ты не робот

Sqlalchemy: как присоединиться к нескольким таблицам по одному запросу?

У меня есть следующие сопоставленные классы SQLAlchemy:

class User(Base):
    __tablename__ = 'users'
    email = Column(String, primary_key=True)
    name = Column(String)

class Document(Base):
    __tablename__ = "documents"
    name = Column(String, primary_key=True)
    author = Column(String, ForeignKey("users.email"))

class DocumentsPermissions(Base):
    __tablename__ = "documents_permissions"
    readAllowed = Column(Boolean)
    writeAllowed = Column(Boolean)

    document = Column(String, ForeignKey("documents.name"))

Мне нужно получить таблицу, подобную этой для user.email = "[email protected]":

email | name | document_name | document_readAllowed | document_writeAllowed

Как это сделать, используя один запрос для SQLAlchemy? Код ниже не работает для меня:

result = session.query(User, Document, DocumentPermission).filter_by(email = "[email protected]").all()

Спасибо,

4b9b3361

Ответ 1

Попробуйте это

q = Session.query(User,Document,DocumentPermissions).filter(User.email == Document.author).\
    filter(Document.name == DocumentPermissions.document).\
    filter(User.email == 'someemail').all()

Ответ 2

Хорошим стилем было бы установить некоторые отношения и первичный ключ для разрешений (на самом деле, обычно это хороший стиль для настройки целочисленных первичных ключей для всего, но что угодно):

class User(Base):
    __tablename__ = 'users'
    email = Column(String, primary_key=True)
    name = Column(String)

class Document(Base):
    __tablename__ = "documents"
    name = Column(String, primary_key=True)
    author_email = Column(String, ForeignKey("users.email"))
    author = relation(User, backref='documents')

class DocumentsPermissions(Base):
    __tablename__ = "documents_permissions"
    id = Column(Integer, primary_key=True)
    readAllowed = Column(Boolean)
    writeAllowed = Column(Boolean)
    document_name = Column(String, ForeignKey("documents.name"))
    document = relation(Document, backref = 'permissions')

Затем выполните простой запрос с объединениями:

query = session.query(User, Document, DocumentsPermissions).join(Document).join(DocumentsPermissions)

Ответ 3

Развернув ответ Abdul, вы можете получить KeyedTuple вместо дискретного набора строк, соединяя столбцы:

q = Session.query(*User.__table__.columns + Document.__table__.columns).\
        select_from(User).\
        join(Document, User.email == Document.author).\
        filter(User.email == 'someemail').all()

Ответ 4

Эта функция создаст требуемую таблицу в виде списка кортежей.

def get_documents_by_user_email(email):
    query = session.query(User.email, User.name, Document.name,
         DocumentsPermissions.readAllowed, DocumentsPermissions.writeAllowed,)
    join_query = query.join(Document).join(DocumentsPermissions)
    return join_query.filter(User.email == email).all()

user_docs = get_documents_by_user_email(email)