association_table is not needed here, forgot to remove it, when minimizing the code, sorry.
On Thursday, 30 November 2017 16:41:05 UTC+3, Анатолий Иванов wrote: > > Hello everyone! > > > *TL;DR:* > A mapping (class A) has a relationship(to class B). Lazy load is > specified. I want to > > 1. manually select and filter data from B (the result lets call B') > 2. select everything from A > 3. outer join A with B' > > Problem: when doing > > all_b = session.query(B).filter(B.value == 1).subquery() > all_a = session.query(A).join(all_b).all() > > it performs correct SQL request, although, when accessing all_a.b performs > an extra SQL request and selects all B (not B'). How do i make select with > the joined data from my subquery instead of selecting whole data from the > database? > > *Long with working code:* > > I do some kind of scanner management. Each IP can have several open ports. > > import datetime > from sqlalchemy import create_engine > from sqlalchemy.orm import sessionmaker > from sqlalchemy.pool import NullPool > from sqlalchemy.orm import aliased, joinedload > > from sqlalchemy.orm import relationship > from sqlalchemy.ext.declarative import declarative_base > from sqlalchemy import Column, String, ForeignKey, Table, Integer, DateTime > > > Base = declarative_base() > > association_table = Table( > '_association', Base.metadata, > Column('ip_id', Integer, ForeignKey('_ips.ip_id')), > Column('host_id', Integer, ForeignKey('_hosts.host_id')) > ) > > class Sessions(object): > > def __init__(self): > self.engine = create_engine('postgresql://127.0.0.1/black', > poolclass=NullPool, echo=True) > self.session_builder = sessionmaker(bind=self.engine, > expire_on_commit=False) > > def get_new_session(self): > session = self.session_builder() > > return session > > def destroy_session(self, session): > session.close() > > class IPDatabase(Base): > __tablename__ = '_ips' > > ip_id = Column(Integer, primary_key=True, autoincrement=True) > > # The hostnames that point to this IP > hostnames = relationship( > "HostDatabase", > secondary=association_table, > back_populates="ip_addresses", > lazy='select' > ) > > # Open ports > ports = relationship('PortDatabase', cascade="all, delete-orphan", > lazy='select') > date_added = Column(DateTime, default=datetime.datetime.utcnow) > > def __repr__(self): > return """ IP=(id={}, ports={}) """.format(self.ip_id, self.ports) > > > class PortDatabase(Base): > __tablename__ = '_ports' > > ports_id = Column(Integer, primary_key=True, autoincrement=True) > > data = Column(String) > port_number = Column(Integer) > > date_added = Column(DateTime, default=datetime.datetime.utcnow) > > > # The name of the related project > target = Column( > Integer, ForeignKey('_ips.ip_id', ondelete='CASCADE') > ) > > > def __repr__(self): > return """ Port=(id={}, port={}) """.format(self.ports_id, > self.port_number) > > > def create(): > sessions = Sessions() > > Base.metadata.drop_all(sessions.engine) > Base.metadata.create_all(sessions.engine, checkfirst=True) > > session_spawner = Sessions() > session = session_spawner.get_new_session() > > ip_1 = IPDatabase() > ip_2 = IPDatabase() > ip_3 = IPDatabase() > > port_1 = PortDatabase(port_number=80) > port_2 = PortDatabase(port_number=80) > port_3 = PortDatabase(port_number=443) > > ip_1.ports.append(port_1) > ip_1.ports.append(port_2) > ip_1.ports.append(port_3) > > session.add(ip_1) > session.add(ip_2) > session.add(ip_3) > > session.add(port_1) > session.add(port_2) > session.add(port_3) > > session.commit() > > session_spawner.destroy_session(session) > > def main(): > session_spawner = Sessions() > session = session_spawner.get_new_session() > > subq = session.query(PortDatabase).filter(PortDatabase.port_number == > 80).subquery() > > ips = session.query(IPDatabase).join(subq).all() > > session_spawner.destroy_session(session) > > print(ips) # This will fail, as 'ports' were not loaded due to > lazyload='select' > > if __name__ == '__main__': > main() > > > Any help would be really great, as i have read tons of manuals and other > resources, but still cannot find the solution. > > Thanks, > Anatoly > -- SQLAlchemy - The Python SQL Toolkit and Object Relational Mapper http://www.sqlalchemy.org/ To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description. --- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.