Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7049233
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T02:59:18+00:00 2026-05-28T02:59:18+00:00

I have two tables. With Sqlalchemy, I map them to two classes: class A(base):

  • 0

I have two tables. With Sqlalchemy, I map them to two classes:

class A(base):
  ...
  id = Column(BigInteger, primary_key=True, autoincrement=True)

class B(base):
  ...
  id = Column(BigInteger, primary_key=True, autoincrement=True)
  a_id = Column(BigInteger, ForeignKey(A.id))
  timestamp = Column(DateTime)

  a = relationship(A, backref="b_s")

I can use A.b_s to get a collection of B objects whose foreign key are as same as the primary key of A. It’s very easy to use lazy load or eager load. But now I have a question. I don’t want to load all B objects. I only want to load the first N objects ordered by timestamp. That is to say, A.b_s only loads some of related B objects. How can I use Sqlalchemy to do it?

Thanks a lot!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T02:59:18+00:00Added an answer on May 28, 2026 at 2:59 am

    What you want to achive will not work with relations (and this is not a SA limitation, rather the proper way to treat relations and take care of the referential integrity).
    However a simple query (wrapped in a method) will do the trick just fine:

    class A(Base):
        # ...
        def get_children(self, offset, count):
            # @todo: might need to handle some border cases
            qry = B.query.with_parent(self)
            #or: qry = object_session(self).query(B).with_parent(self)
            return qry[offset:offset+count]
    
    my_a = session.query(A).get(a_id)
    print my_a.get_children( 0, 10) # print first 10 children
    print my_a.get_children(10, 10) # print second 10 children
    

    edit-1: achieve that by having only 1-2 SQL statements
    Now, to achieve this in only 1-2 SQL statements is definitely possible.
    First of all, one needs a way to get the identifiers of B for top N of each A. For this we will use the sqlalchemy.sql.expression.over function to compose a subquery:

    # @note: this is the subquery using *sqlalchemy.orm.over* function to limit number of rows
    # this subquery is used for both queries below
    # @note: the code below sorts Bs by id, but you can change it in order_by
    subq = (session.query(
                B.__table__.c.id.label("b_id"), 
                over(func.row_number(), partition_by="a_id", order_by="id").label("rownum")
           ).subquery())
    # this produces the following SQL (@note: the RDBMS should support the OVER...)
    # >> SELECT b.id AS b_id, row_number() OVER (PARTITION BY a_id ORDER BY id) AS rownum FROM b
    

    Version-1:
    Now, the first version will load As, the second will load Bs. The function returns dictionary with As as keys and list of Bs as values:

    def get_A_with_Bs_in_batch(b_limit=10):
        """ 
        @return: dict(A, [list of top *b_limit* A.b_s])  
        @note: uses 2 SQL statements, but does not screw up relationship.
        @note: if the relationship is requested via a_instance.b_s, the new SQL statement will be
        issued to load *all* related objects
        """
        qry_a = session.query(A)
        qry_b = (session.query(B)
                .join(subq, and_(subq.c.b_id == B.id, subq.c.rownum <= b_limit))
                )
        a_s = qry_a.all()
        b_s = qry_b.all()
        res = dict((a, [b for b in b_s if b.a == a]) for a in a_s)
        return res
    

    Version-2: this will trick SQLAlchemy to think that the TOP N Bs that are loaded in single query with A is actually A.b_s. VERY DANGEROUS, but neat. Read the comments in code which explain the pieces:

    def get_A_with_Bs_hack_relation(b_limit=10):
        """ 
        @return: dict(A, [list of top *b_limit* A.b_s])
        @note: the Bs are loaded as relationship A.b_s, but with the limit.
        """
        qry = (session.query(A)
                .outerjoin(B)
                # @note: next line will trick SA to load joined Bs as if they were *all* objects
                # of relationship A.b_s. this is a @hack: and one should discard/reset a session after this
                # kind of hacky query!!!
                .options(contains_eager(A.b_s))
                .outerjoin(subq, and_(subq.c.b_id == B.id, subq.c.rownum <= b_limit))
                # @note: next line is required to make both *outerjoins* to play well together 
                # in order produce the right result
                .filter(or_(B.id == None, and_(B.id != None, subq.c.b_id != None)))
                )
        res = dict((a, a.b_s) for a in qry.all())
        return res
    

    To summarize, the Version-2 is probably the most direct answer to your question. Use it at own risk, because here you are tricking SA big time and if you modify the relationship property in any way, you might experience “Kaboom!”

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

SqlAlchemy newbie question: Base = declarative_base() class A(Base): __tablename__ = 'as' id = Column(Integer,
I'm using Turbogears2 and SQLAlchemy to develop a webapp. I have two mapped tables
Let's consider the following table models for sqlalchemy in python. class Worker(Base): id Column(Integer,
Using SQLAlchemy , I have a one to many relation with two tables -
In user_models.py , I have this: class Users(Base): __tablename__ = 'account_users' id = Column(Integer,
Have two tables with a linking table between them. USERS +-------+---------+ | userID| Username|
I have two tables that are joined together. A has many B Normally you
I have two tables, Book and Tag , and books are tagged using the
We have two Tables: Document: id, title, document_type_id, showon_id DocumentType: id, name Relationship: DocumentType
I have two tables, both with start time and end time fields. I need

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.