python - how to do a query with multi-table related sqlalchemy -
i have next models.
class provider(base): __tablename__ = "providers" providerid = column(integer, primary_key=true) thirdpartyid = column(integer, foreignkey("thirdparties.thirdpartyid")) thirdparty = relationship("thirdparty") class thirdparty(base): __tablename__ = 'thirdparties' thirdpartyid = column(integer, primary_key=true, nullable=false) economicactivityid = column(integer, foreignkey('economicactivities.economicactivityid')) class economicactivity(base): __tablename__ = 'economicactivities' economicactivityid = column(integer, primary_key=true, nullable=false) puc = relationship(u'puc', secondary=economicactivitypuc, primaryjoin=economicactivityid == economicactivitypuc.c.economicactivityid, secondaryjoin=puc.pucid == economicactivitypuc.c.pucid, lazy="dynamic") economicactivitypuc = table( 'economicactivitypuc', base.metadata, column('economicactivityid', foreignkey(u'economicactivities.economicactivityid'), primary_key=true, nullable=false), column('pucid', foreignkey(u'puc.pucid'), primary_key=true, nullable=false, index=true)) class puc(base): __tablename__ = "puc" pucid = column(integer, primary_key=true, nullable=false)
this query:
list_provider = [provider.export_data_simple_search(provider) provider in session.query(provider.providerid, provider.branch, provider.name, provider.ismain, provider.companyid, thirdparty.iswithholdingcree, thirdparty.thirdpartyid, thirdparty.tradename, thirdparty.lastname, thirdparty.maidenname, thirdparty.firstname, thirdparty.identificationnumber, economicactivity,) # .options(defer(provider.cityid)) .join(thirdparty, thirdparty.thirdpartyid == provider.thirdpartyid) .join(economicactivity, thirdparty.economicactivityid == economicactivity.economicactivityid) .filter(and_( provider.companyid == company_id, or_( true if search == "" else none, # or_(*[provider.name.like('%{0}%'.format(s)) s in words]) or_(*[func.concat(thirdparty.tradename + thirdparty.lastname + thirdparty.maidenname + thirdparty.firstname + thirdparty.identificationnumber + provider.name).like('%{0}%'.format(s)) s in words] )))) .limit(page_size) .offset((int(page_number) - 1) * int(page_size))] total_count = session.query(provider).filter(and_( provider.companyid == company_id, or_( true if search == "" else none, # or_(*[provider.name.like('%{0}%'.format(s)) s in words]) or_(*[func.concat(thirdparty.tradename + thirdparty.lastname + thirdparty.maidenname + thirdparty.firstname + thirdparty.identificationnumber + provider.name).like('%{0}%'.format(s)) s in words] )))).count() total_pages = int(ceil(total_count / float(page_size))) response = jsonify({ 'listthirdparty': list_provider, 'totalcount': total_count, 'totalpages': total_pages }) return response
and export_data method next:
class provider(base): ##### models, anothers methods, etc @staticmethod def export_data_simple_search(data): pucs = none if data.economicactivity none \ else data.economicactivity.puc.filter(puc.companyid == data.companyid).first() return { "providerid": data.providerid, "branch": data.branch, "puc": none if pucs none else { "pucid": pucs.pucid, "companyid": pucs.companyid, "account": '{0}{1}{2}{3}{4} {5}'.format(pucs.pucclass, pucs.pucsubclass, pucs.account, pucs.subaccount, pucs.auxiliary1, pucs.name), "percentage": pucs.percentage, "name": pucs.name, }, "thirdpartyid": data.thirdpartyid }
i need query bring me data from: provider > thirdparty > economicactivity >m2m (filter companyid)> puc
this implementation works, takes around 25secs page, need skip step:
data.economicactivity.puc.filter(puc.companyid == data.companyid).first()
because it's doing 15(page size) new selects.
Comments
Post a Comment