Loading Page Content...
Preparing courses, live labs, and learning resources.सामग्री लोड हो रही है, कृपया प्रतीक्षा करें...
Preparing courses, live labs, and learning resources.सामग्री लोड हो रही है, कृपया प्रतीक्षा करें...
Relational database systems gain their expressive power from table associations: One-to-Many (1:N), Many-to-One (N:1), Many-to-Many (M:N), and One-to-One (1:1). In SQLAlchemy 2.0, relationships are configured using ForeignKey constraints paired with high-level relationship() property descriptors, enabling bidirectional navigation and automated cascading lifecycles.
Consider a standard domain model: an Author writes multiple Articles.
back_populatesback_populates instead of legacy backref. back_populates explicitly documents the relationship on both classes, providing full IDE autocompletion, static type checking, and clean bidirectional synchronization.In a Many-to-Many association (e.g. Students enrolled in multiple Courses), relational databases require an intermediate Association Table containing foreign keys referencing both primary keys:
By default, SQLAlchemy loads relationship collections lazily—it issues a separate SELECT query only when the attribute is first accessed in Python:
selectinload & joinedload)The sqlalchemy.orm module provides relationship loaders to eliminate the N+1 problem:
selectinload: Issues a single SELECT ... WHERE id IN (...) query to fetch all related items in bulk. (Best for 1:N collections).joinedload: Emits an SQL LEFT OUTER JOIN to fetch both parent and child rows in one query. (Best for N:1 and 1:1 scalar references).all, delete-orphanConfiguring cascade="all, delete-orphan" ensures database cleanliness:
Author is deleted, all their associated Article records are deleted automatically.Article is removed from author.articles.remove(art), the orphaned article record is deleted from the database instead of lingering with a NULL foreign key.| Relationship | Prerequisite | SQLAlchemy Syntax | Recommended Eager Loader |
|---|---|---|---|
| One-to-Many (1:N) | ForeignKey on child table | relationship(back_populates="...", cascade="all, delete-orphan") | selectinload() |
| Many-to-One (N:1) | ForeignKey on this table | relationship(back_populates="...") | joinedload() |
| Many-to-Many (M:N) | Association Table | relationship(secondary=link_table, back_populates="...") | selectinload() |
| One-to-One (1:1) | Unique ForeignKey | Mapped[Child] = relationship(...) (scalar type) | joinedload() |
Iterating over child relationships in a loop with default lazy loading executes 1 query for the parent plus N separate queries for the children. Use selectinload() or joinedload() to eager-load relationships in bulk.
When deleting parent records, configure cascade="all, delete-orphan" on relationships to prevent orphaned foreign keys in child tables.
Model an Author with many Book instances in SQLAlchemy. Verify that deleting an author automatically cascades and purges all their associated books.
What problem occurs when accessing lazy-loaded relationship attributes inside a loop over $N$ parent objects? A. The N+1 Query Problem: $1$ query fetches the parents, followed by $N$ separate queries fetching each parent's children. B. A DeadlockError on the primary key. C. All records are deleted automatically. D. Sockets are permanently closed.
Which eager loading strategy emits a SELECT ... WHERE parent_id IN (...) query to efficiently load One-to-Many collections in bulk? A. lazyload() B. selectinload() C. subqueryload() D. noload()
selectinload() loads related collections using an efficient IN query that loads all child records corresponding to parent primary keys in a single second query.What is the effect of specifying cascade="all, delete-orphan" on a parent model's relationship()? A. Child objects are deleted when their parent is deleted, and children removed from the parent's collection are also deleted from the database. B. Child objects are converted into JSON strings. C. Deleting the parent is blocked by a ForeignKeyViolation. D. Foreign keys are automatically set to -1.
delete-orphan instructs SQLAlchemy to delete child records from the database if their parent is deleted or if they are detached from the parent's relationship collection.How is a Many-to-Many relationship configured between two models in SQLAlchemy? A. By placing two foreign keys on the same table. B. By defining an intermediate Association Table and referencing it via relationship(secondary=association_table). C. By using Python's multiprocessing.Queue. D. By duplicating all table columns.
secondary argument of relationship().Why is back_populates preferred over backref in modern SQLAlchemy 2.0? A. backref only works on PostgreSQL. B. back_populates requires explicit declarations on both participating classes, improving code clarity, IDE autocompletion, and static type checking. C. backref runs slower in SQLite. D. back_populates creates automated database indexes.
back_populates ensures strict type annotations and clarity, avoiding the implicit attribute creation caused by legacy backref.In the next lesson, we will continue your advanced Python journey with Transactions and Rollbacks (9: Advanced Database Handling).
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
| Previous Lesson | Next Lesson |
|---|---|
| SQLAlchemy ORM Basics | Transactions and Rollbacks |
Test your understanding of this lesson with 5 questions. Each question has one correct answer.