Database Tutorials Relationships এবং Joins গাইড ও নোট

427

SQLAlchemy তে Relationships এবং Joins দুটি গুরুত্বপূর্ণ ধারণা, যা ডেটাবেস টেবিলের মধ্যে সম্পর্ক তৈরি এবং ডেটা একত্রিত করতে ব্যবহৃত হয়। Relationships অবজেক্ট-ওরিয়েন্টেড পদ্ধতিতে টেবিলের মধ্যে সম্পর্ক নির্ধারণ করে, এবং Joins SQL এর মাধ্যমে বিভিন্ন টেবিলের ডেটা একত্রিত করতে ব্যবহৃত হয়।


Relationships

SQLAlchemy তে Relationships ব্যবহার করে একাধিক টেবিলের মধ্যে সম্পর্ক (One-to-One, One-to-Many, Many-to-Many) তৈরি করা হয়। ORM (Object Relational Mapping) এর মাধ্যমে এই সম্পর্ক সহজে মডেল করা সম্ভব হয়। Relationships ডেটাবেসের মধ্যে সম্পর্কিত তথ্যের সাথে কাজ করার জন্য একটি অবজেক্ট-ওরিয়েন্টেড পদ্ধতি সরবরাহ করে।

Relationship এর প্রধান ধরনের সম্পর্ক:

  • One-to-One Relationship: এক টেবিলের একটি রেকর্ডের সাথে অন্য টেবিলের এক রেকর্ড সম্পর্কিত।
  • One-to-Many Relationship: এক টেবিলের একটি রেকর্ডের সাথে অন্য টেবিলের একাধিক রেকর্ড সম্পর্কিত।
  • Many-to-Many Relationship: একাধিক রেকর্ড একাধিক রেকর্ডের সাথে সম্পর্কিত।

উদাহরণ (One-to-Many Relationship):

ধরা যাক, আমাদের একটি Parent টেবিল এবং একটি Child টেবিল রয়েছে, যেখানে Parent এর একটি রেকর্ডের সাথে অনেকগুলো Child রেকর্ড সম্পর্কিত।

from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# Base ক্লাস তৈরি
Base = declarative_base()

# Parent ক্লাস
class Parent(Base):
    __tablename__ = 'parents'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    
    # One-to-Many relationship
    children = relationship('Child', back_populates='parent')

# Child ক্লাস
class Child(Base):
    __tablename__ = 'children'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    parent_id = Column(Integer, ForeignKey('parents.id'))
    
    # Parent এর সাথে সম্পর্ক
    parent = relationship('Parent', back_populates='children')

# ডেটাবেস ইঞ্জিন তৈরি
engine = create_engine('sqlite:///example.db', echo=True)

# টেবিল তৈরি করা
Base.metadata.create_all(engine)

# Session তৈরি
Session = sessionmaker(bind=engine)
session = Session()

# নতুন Parent এবং Child তৈরি করা
parent = Parent(name='John')
child1 = Child(name='Anna', parent=parent)
child2 = Child(name='Mike', parent=parent)

# Parent এবং Children ডেটাবেসে সেভ করা
session.add(parent)
session.commit()

# Parent এর children রিড করা
retrieved_parent = session.query(Parent).first()
print(retrieved_parent.children)  # Parent এর children দেখাবে

# Session বন্ধ করা
session.close()

এখানে Parent এবং Child এর মধ্যে One-to-Many সম্পর্ক তৈরি করা হয়েছে। parent.children এর মাধ্যমে Lazy Loading এর মাধ্যমে Parent এর সকল Child রেকর্ড পাওয়া যাবে।


Joins

SQLAlchemy তে Joins ব্যবহৃত হয় একাধিক টেবিলের ডেটা একত্রিত করতে। SQL JOIN স্টেটমেন্টের মাধ্যমে আমরা দুই বা ততোধিক টেবিলের মধ্যে সম্পর্কিত ডেটা একত্রিত করতে পারি। SQLAlchemy তে Joins সরাসরি join() ফাংশন ব্যবহার করে করা হয়।

উদাহরণ (Inner Join):

ধরা যাক, আমাদের Parent এবং Child টেবিল আছে এবং আমরা তাদের সম্পর্কিত ডেটা একত্রিত করতে চাই।

from sqlalchemy import create_engine, Table, Column, Integer, String, ForeignKey
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import aliased

# Base ক্লাস তৈরি
Base = declarative_base()

# Parent ক্লাস
class Parent(Base):
    __tablename__ = 'parents'
    id = Column(Integer, primary_key=True)
    name = Column(String)

# Child ক্লাস
class Child(Base):
    __tablename__ = 'children'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    parent_id = Column(Integer, ForeignKey('parents.id'))

# ডেটাবেস ইঞ্জিন তৈরি
engine = create_engine('sqlite:///example.db', echo=True)

# টেবিল তৈরি করা
Base.metadata.create_all(engine)

# Session তৈরি
Session = sessionmaker(bind=engine)
session = Session()

# Parent এবং Child এর মধ্যে Joins
result = session.query(Parent, Child).join(Child).all()

for parent, child in result:
    print(f"Parent: {parent.name}, Child: {child.name}")

# Session বন্ধ করা
session.close()

এখানে, Inner Join এর মাধ্যমে Parent এবং Child টেবিলের সম্পর্কিত ডেটা একত্রিত করা হয়েছে। join() ফাংশন ব্যবহার করে আমরা Parent এবং Child টেবিলের ডেটা মিলিয়েছি।


Joins এর অন্যান্য ধরনের সম্পর্ক

  • Left Join (Left Outer Join): Left join ব্যবহার করে আপনি সেই রেকর্ডগুলি পেতে পারেন যেগুলি মূল টেবিলের সাথে মেলে না, কিন্তু যেগুলি সম্পর্কিত টেবিল থেকে আসছে।

    result = session.query(Parent, Child).join(Child, isouter=True).all()
    
  • Right Join (Right Outer Join): Right join ব্যবহার করা হয় উল্টোভাবে। এখানে মূল টেবিলের রেকর্ডগুলি এবং সম্পর্কিত টেবিলের সমস্ত রেকর্ড মেলানো হয়।
  • Full Join (Full Outer Join): Full join মূলত উভয় টেবিলের সকল রেকর্ড একত্রিত করে, যেখানে কিছু রেকর্ড সম্পর্কিত টেবিলের সঙ্গে না মেলেও থাকতে পারে।

Relationship এবং Join এর মধ্যে পার্থক্য

  • Relationship: ORM এর মাধ্যমে টেবিলের মধ্যে অবজেক্ট-ওরিয়েন্টেড সম্পর্ক তৈরি করে, যেখানে ডেটা ডেভেলপাররা Python অবজেক্টের মাধ্যমে হ্যান্ডল করতে পারেন।
  • Join: SQL এর মাধ্যমে ডেটাবেসের মধ্যে সম্পর্কিত টেবিলগুলির ডেটা একত্রিত করতে ব্যবহৃত হয়।

সারাংশ

Relationships এবং Joins SQLAlchemy তে ডেটাবেস টেবিলের মধ্যে সম্পর্ক তৈরি এবং ডেটা একত্রিত করার জন্য অত্যন্ত গুরুত্বপূর্ণ উপাদান। Relationships অবজেক্ট-ওরিয়েন্টেড পদ্ধতিতে সম্পর্ক তৈরি করতে সাহায্য করে, যেখানে Joins SQL কিউরি ব্যবহারের মাধ্যমে ডেটাবেস টেবিলগুলির মধ্যে সম্পর্কিত ডেটা একত্রিত করতে ব্যবহৃত হয়। One-to-Many, One-to-One, এবং Many-to-Many সম্পর্কগুলি SQLAlchemy তে সহজে মডেল করা যায় এবং SQL join() ফাংশন ব্যবহার করে বিভিন্ন টেবিলের ডেটা একত্রিত করা সম্ভব।

Content added By

One-to-One, One-to-Many, এবং Many-to-Many Relationships

344

SQLAlchemy তে One-to-One, One-to-Many, এবং Many-to-Many সম্পর্ক (relationships) মডেলিংয়ের জন্য শক্তিশালী সমর্থন রয়েছে। এসব সম্পর্ক ডেটাবেসের টেবিলের মধ্যে সম্পর্ক স্থাপন করে এবং ডেটাবেসের অপারেশনগুলো সহজে সম্পন্ন করতে সহায়তা করে। SQLAlchemy ORM এর মাধ্যমে এই সম্পর্কগুলোকে Python ক্লাসের মাধ্যমে মডেল করা যায়।


One-to-One Relationship

One-to-One সম্পর্ক একটি সম্পর্ক যেখানে একটি রেকর্ড অন্য একটি রেকর্ডের সাথে একযোগে সম্পর্কিত থাকে। অর্থাৎ, একটি Parent টেবিলের একটি রেকর্ডের সাথে একটি Child টেবিলের একটি রেকর্ড সম্পর্কিত থাকে।

উদাহরণ:

ধরা যাক, আমাদের একটি User টেবিল এবং একটি Profile টেবিল রয়েছে। প্রতিটি User এর একটি Profile থাকবে, এবং প্রতিটি Profile শুধুমাত্র একটি User এর সাথে সম্পর্কিত থাকবে।

from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# Base তৈরি
Base = declarative_base()

# User ক্লাস (One-to-One Relationship)
class User(Base):
    __tablename__ = 'users'
    
    id = Column(Integer, primary_key=True)
    name = Column(String)

    # User এর সাথে সম্পর্কিত Profile
    profile = relationship("Profile", back_populates="user", uselist=False)

# Profile ক্লাস
class Profile(Base):
    __tablename__ = 'profiles'

    id = Column(Integer, primary_key=True)
    bio = Column(String)
    user_id = Column(Integer, ForeignKey('users.id'))

    # Profile এর সাথে সম্পর্কিত User
    user = relationship("User", back_populates="profile")

# SQLite ডেটাবেসের জন্য ইঞ্জিন তৈরি
engine = create_engine('sqlite:///example.db', echo=True)

# টেবিল তৈরি
Base.metadata.create_all(engine)

# সেশন তৈরি
Session = sessionmaker(bind=engine)
session = Session()

# নতুন ইউজার এবং প্রোফাইল ইনসার্ট করা
new_user = User(name="John Doe", profile=Profile(bio="Software Developer"))
session.add(new_user)
session.commit()

# ডেটা ফেচ করা
user = session.query(User).first()
print(user.name, user.profile.bio)

এখানে, User এবং Profile এর মধ্যে One-to-One সম্পর্ক তৈরি করা হয়েছে। User এর একটি Profile আছে, এবং Profile শুধুমাত্র একটিই User এর সাথে সম্পর্কিত।


One-to-Many Relationship

One-to-Many সম্পর্ক একটি সম্পর্ক যেখানে একটি Parent টেবিলের একটি রেকর্ড একাধিক Child টেবিলের রেকর্ডের সাথে সম্পর্কিত থাকে। উদাহরণস্বরূপ, একটি Author এর অনেকগুলো Book থাকতে পারে।

উদাহরণ:

ধরা যাক, আমাদের একটি Author টেবিল এবং একটি Book টেবিল রয়েছে, যেখানে একটি Author এর অনেকগুলো Book থাকতে পারে।

from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# Base তৈরি
Base = declarative_base()

# Author ক্লাস (One-to-Many Relationship)
class Author(Base):
    __tablename__ = 'authors'
    
    id = Column(Integer, primary_key=True)
    name = Column(String)

    # Author এর সাথে সম্পর্কিত Book
    books = relationship("Book", back_populates="author")

# Book ক্লাস
class Book(Base):
    __tablename__ = 'books'

    id = Column(Integer, primary_key=True)
    title = Column(String)
    author_id = Column(Integer, ForeignKey('authors.id'))

    # Book এর সাথে সম্পর্কিত Author
    author = relationship("Author", back_populates="books")

# SQLite ডেটাবেসের জন্য ইঞ্জিন তৈরি
engine = create_engine('sqlite:///example.db', echo=True)

# টেবিল তৈরি
Base.metadata.create_all(engine)

# সেশন তৈরি
Session = sessionmaker(bind=engine)
session = Session()

# নতুন Author এবং Books ইনসার্ট করা
new_author = Author(name="J.K. Rowling", books=[Book(title="Harry Potter and the Philosopher's Stone"), Book(title="Harry Potter and the Chamber of Secrets")])
session.add(new_author)
session.commit()

# ডেটা ফেচ করা
author = session.query(Author).first()
print(author.name)
for book in author.books:
    print(book.title)

এখানে, One-to-Many সম্পর্কটি Author এবং Book টেবিলের মধ্যে তৈরি করা হয়েছে। একটি Author এর অনেকগুলো Book থাকতে পারে।


Many-to-Many Relationship

Many-to-Many সম্পর্ক একটি সম্পর্ক যেখানে একাধিক Parent টেবিলের রেকর্ড অনেকগুলো Child টেবিলের রেকর্ডের সাথে সম্পর্কিত থাকে। উদাহরণস্বরূপ, একটি Student এর অনেকগুলো Course থাকতে পারে এবং একটি Course এর অনেকগুলো Student থাকতে পারে। এই সম্পর্কটি একটি association table এর মাধ্যমে তৈরি করা হয়।

উদাহরণ:

ধরা যাক, আমাদের একটি Student টেবিল এবং একটি Course টেবিল রয়েছে। একটি Student এর অনেকগুলো Course থাকতে পারে এবং একটি Course এর অনেকগুলো Student থাকতে পারে।

from sqlalchemy import create_engine, Column, Integer, String, ForeignKey, Table
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# Base তৈরি
Base = declarative_base()

# Association table তৈরি
student_course = Table('student_course', Base.metadata,
    Column('student_id', Integer, ForeignKey('students.id')),
    Column('course_id', Integer, ForeignKey('courses.id'))
)

# Student ক্লাস (Many-to-Many Relationship)
class Student(Base):
    __tablename__ = 'students'
    
    id = Column(Integer, primary_key=True)
    name = Column(String)

    # Student এর সাথে সম্পর্কিত Course
    courses = relationship("Course", secondary=student_course, back_populates="students")

# Course ক্লাস
class Course(Base):
    __tablename__ = 'courses'

    id = Column(Integer, primary_key=True)
    name = Column(String)

    # Course এর সাথে সম্পর্কিত Student
    students = relationship("Student", secondary=student_course, back_populates="courses")

# SQLite ডেটাবেসের জন্য ইঞ্জিন তৈরি
engine = create_engine('sqlite:///example.db', echo=True)

# টেবিল তৈরি
Base.metadata.create_all(engine)

# সেশন তৈরি
Session = sessionmaker(bind=engine)
session = Session()

# নতুন Student এবং Courses ইনসার্ট করা
student1 = Student(name="Alice", courses=[Course(name="Math"), Course(name="Science")])
student2 = Student(name="Bob", courses=[Course(name="Math")])
session.add(student1)
session.add(student2)
session.commit()

# ডেটা ফেচ করা
students = session.query(Student).all()
for student in students:
    print(student.name)
    for course in student.courses:
        print(course.name)

এখানে, Many-to-Many সম্পর্কটি Student এবং Course টেবিলের মধ্যে তৈরি করা হয়েছে। student_course association table এর মাধ্যমে এই সম্পর্কটি তৈরি করা হয়েছে।


সারাংশ

SQLAlchemy তে One-to-One, One-to-Many, এবং Many-to-Many সম্পর্ক তৈরি করা সম্ভব এবং এগুলো ডেটাবেসের টেবিলের মধ্যে সম্পর্ক স্থাপন করে। One-to-One সম্পর্কটি দুটি টেবিলের মধ্যে একে অপরের সাথে সম্পর্কিত রেকর্ড তৈরি করে, One-to-Many সম্পর্কটি একটি টেবিলের রেকর্ডকে অন্য একটি টেবিলের একাধিক রেকর্ডের সাথে সম্পর্কিত করে এবং Many-to-Many সম্পর্কটি দুটি টেবিলের মধ্যে একাধিক রেকর্ডের সম্পর্ক স্থাপন করে, যা একটি association table এর মাধ্যমে হয়। SQLAlchemy ORM ব্যবহার করে এই সম্পর্কগুলো সহজে মডেল করা সম্ভব।

Content added By

relationship() এবং backref() এর ব্যবহার

325

SQLAlchemy তে relationship() এবং backref() দুটি অত্যন্ত গুরুত্বপূর্ণ ফিচার, যা ডেটাবেস টেবিলগুলোর মধ্যে সম্পর্ক (relationships) তৈরি করতে ব্যবহৃত হয়। এগুলি Object Relational Mapping (ORM) এর মূল অংশ, যা ডেটাবেসের মধ্যে টেবিলের সম্পর্ককে Python অবজেক্টের মধ্যে রূপান্তরিত করে। এই দুটি ফিচারের মাধ্যমে আপনি ডেটাবেস টেবিলগুলির মধ্যে বিভিন্ন ধরনের সম্পর্ক (One-to-One, One-to-Many, Many-to-Many) তৈরি এবং পরিচালনা করতে পারেন।


relationship() ফাংশন

relationship() হল SQLAlchemy এর ORM ফিচার যা দুইটি টেবিলের মধ্যে সম্পর্ক তৈরি করতে ব্যবহৃত হয়। এটি একটি প্রপার্টি হিসেবে কাজ করে, যা সম্পর্কিত টেবিলের রেকর্ডগুলি অবজেক্ট হিসেবে লোড করতে সক্ষম করে। এটি শুধুমাত্র টেবিল সম্পর্ক মডেল করার জন্য ব্যবহৃত হয় এবং এর মাধ্যমে আপনি One-to-Many, Many-to-One, এবং Many-to-Many সম্পর্ক তৈরি করতে পারেন।

relationship() এর বৈশিষ্ট্য

  • এটি একটি two-way সম্পর্ক তৈরি করতে সহায়তা করে (যেমন, একটি টেবিল থেকে সম্পর্কিত টেবিলের রেকর্ড অ্যাক্সেস করা এবং উল্টোটি)।
  • এটি সম্পর্কিত রেকর্ডগুলি লোড করার জন্য lazy loading বা eager loading এর মতো কৌশল ব্যবহার করতে সহায়তা করে।
  • relationship() ব্যবহার করে আপনি সম্পর্কিত টেবিলের মধ্যে রেফারেন্স তৈরি করতে পারেন, যেমন একজন পিতা-মাতার সাথে সন্তানের সম্পর্ক বা এক ক্লাসের সাথে অন্যান্য ক্লাসের সম্পর্ক।

উদাহরণ:

from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

# Parent টেবিল
class Parent(Base):
    __tablename__ = 'parents'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    
    # One-to-many relationship with Child
    children = relationship("Child", backref="parent")

# Child টেবিল
class Child(Base):
    __tablename__ = 'children'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    parent_id = Column(Integer, ForeignKey('parents.id'))

এখানে, Parent টেবিলের সাথে Child টেবিলের One-to-Many সম্পর্ক তৈরি করা হয়েছে। relationship("Child", backref="parent") এর মাধ্যমে এই সম্পর্ক প্রতিষ্ঠিত হয়েছে। এখানে backref ব্যবহার করা হয়েছে, যা উল্টো দিকেও সম্পর্ক তৈরি করে।


backref() ফাংশন

backref() হল SQLAlchemy তে একটি পদ্ধতি, যা দুটি সম্পর্কিত টেবিলের মধ্যে উল্টো দিকের সম্পর্ক তৈরি করতে ব্যবহৃত হয়। এটি relationship() এর সাথে ব্যবহার করা হয়, এবং এটি ডেটাবেসের উল্টো দিক থেকে সম্পর্কের জন্য একটি virtual attribute তৈরি করে দেয়। এর মাধ্যমে, আপনি সম্পর্কিত টেবিলের মধ্যে সম্পর্কের উল্টো দিক থেকে সহজে অ্যাক্সেস পেতে পারেন।

backref() এর বৈশিষ্ট্য

  • backref() আপনাকে একটি সম্পর্কের উল্টো দিক থেকে সম্পর্কিত টেবিলের অবজেক্ট অ্যাক্সেস করতে সহায়তা করে।
  • এটি এক ধরনের bidirectional relationship তৈরি করে, যেখানে দুটি টেবিলের সম্পর্ক একে অপরের সাথে যুক্ত থাকে।

উদাহরণ:

from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

# Parent টেবিল
class Parent(Base):
    __tablename__ = 'parents'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    
    # One-to-many relationship with Child, backref 'parent' creates reverse relationship
    children = relationship("Child", backref="parent")

# Child টেবিল
class Child(Base):
    __tablename__ = 'children'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    parent_id = Column(Integer, ForeignKey('parents.id'))

এখানে, backref="parent" ব্যবহার করা হয়েছে, যা Child অবজেক্টের মধ্যে parent নামক একটি অতিরিক্ত অ্যাট্রিবিউট তৈরি করে। এর মাধ্যমে, আপনি Child অবজেক্টের মধ্যে সংশ্লিষ্ট Parent অবজেক্ট অ্যাক্সেস করতে পারবেন।

backref ব্যবহার উদাহরণ:

# নতুন Parent এবং Child তৈরি করা
parent1 = Parent(name="John")
child1 = Child(name="Alice", parent=parent1)

# Child থেকে Parent অ্যাক্সেস করা
print(child1.parent.name)  # "John"

# Parent থেকে Child অ্যাক্সেস করা
print(parent1.children[0].name)  # "Alice"

এখানে child1.parent.name ব্যবহার করে Child অবজেক্টের মাধ্যমে সম্পর্কিত Parent অবজেক্ট অ্যাক্সেস করা হয়েছে এবং parent1.children[0].name এর মাধ্যমে Parent অবজেক্টের মাধ্যমে সম্পর্কিত Child অবজেক্ট অ্যাক্সেস করা হয়েছে।


One-to-Many এবং Many-to-One সম্পর্ক

One-to-Many সম্পর্কের মধ্যে একটি পিতা-মাতা টেবিল একাধিক সন্তান টেবিলের রেকর্ডের সাথে সম্পর্কিত। আর Many-to-One সম্পর্কের মধ্যে একাধিক সন্তান টেবিলের রেকর্ড একটি পিতা-মাতা টেবিলের সাথে সম্পর্কিত।

উদাহরণ (One-to-Many):

# One-to-many relationship
parent = Parent(name="Alice")
child1 = Child(name="John", parent=parent)
child2 = Child(name="Jane", parent=parent)
session.add(parent)
session.commit()

# Parent থেকে Child রেকর্ড পেতে
parent_children = parent.children  # পিতা-মাতার সাথে সম্পর্কিত সমস্ত সন্তান

এখানে, Parent অবজেক্টের children প্রপার্টি ব্যবহার করে সম্পর্কিত multiple Child অবজেক্ট অ্যাক্সেস করা হয়েছে।


Many-to-Many সম্পর্ক

Many-to-Many সম্পর্কের মধ্যে দুটি টেবিলের মধ্যে অনেকগুলো রেকর্ড একে অপরের সাথে সম্পর্কিত থাকে। SQLAlchemy তে এই সম্পর্ক তৈরি করতে একটি association table ব্যবহার করা হয়, যা দুইটি টেবিলের মধ্যে সম্পর্ক ধারণ করে।

উদাহরণ (Many-to-Many):

from sqlalchemy import Table, ForeignKey
from sqlalchemy.orm import relationship

# Association table between Student and Course
student_course_association = Table('student_course', Base.metadata,
    Column('student_id', Integer, ForeignKey('students.id')),
    Column('course_id', Integer, ForeignKey('courses.id'))
)

class Student(Base):
    __tablename__ = 'students'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    courses = relationship("Course", secondary=student_course_association, backref="students")

class Course(Base):
    __tablename__ = 'courses'
    id = Column(Integer, primary_key=True)
    name = Column(String)

এখানে, Student এবং Course টেবিলের মধ্যে Many-to-Many সম্পর্ক তৈরি করা হয়েছে। student_course_association টেবিলটি দুটি টেবিলের মধ্যে সম্পর্ক সংরক্ষণ করে।


সারাংশ

  • relationship() এবং backref() SQLAlchemy ORM তে টেবিলের মধ্যে সম্পর্ক তৈরি এবং পরিচালনার জন্য ব্যবহৃত হয়।
  • relationship() একটি সম্পর্ক তৈরি করতে সাহায্য করে, যেমন One-to-Many, Many-to-One, এবং Many-to-Many।
  • backref() দুটি সম্পর্কিত টেবিলের মধ্যে উল্টো দিকের সম্পর্ক তৈরি করে, যাতে আপনি এক টেবিল থেকে সম্পর্কিত অন্য টেবিলের রেকর্ড অ্যাক্সেস করতে পারেন।
  • এই দুটি ফিচার একে অপরের সাথে কাজ করে ডেটাবেস সম্পর্ককে অবজেক্ট-ওরিয়েন্টেডভাবে সহজ করে তোলে।
Content added By

Lazy Loading এবং Eager Loading এর ধারণা

345

Lazy Loading এবং Eager Loading হল ডেটাবেস থেকে সম্পর্কিত ডেটা লোড করার দুটি ভিন্ন কৌশল। SQLAlchemy ORM (Object Relational Mapping) এ এই দুটি কৌশল ব্যবহৃত হয়, যা ডেটাবেসের সাথে সম্পর্কিত অবজেক্টগুলো লোড করার সময় ব্যবহৃত হয়।


Lazy Loading

Lazy Loading একটি কৌশল, যেখানে সম্পর্কিত অবজেক্টগুলি অবিলম্বে লোড করা হয় না, তবে এগুলোকে প্রয়োজনের সময় লোড করা হয়। যখন আপনি কোনো অবজেক্টের সাথে সম্পর্কিত ডেটা অ্যাক্সেস করতে চেষ্টা করেন, তখন SQLAlchemy তখনই সম্পর্কিত ডেটা লোড করবে। এটি ডেটাবেস অপারেশনগুলোর মধ্যে সর্বনিম্ন সঞ্চালন করে এবং শুধুমাত্র যখন ডেটার প্রয়োজন হয়, তখনই ডেটা লোড হয়।

বৈশিষ্ট্য:

  • প্রাথমিক লোডিং: শুধুমাত্র অবজেক্টের প্রাথমিক ডেটা লোড হয়। সম্পর্কিত ডেটা পরবর্তী সময়ে লোড করা হয়।
  • পারফরম্যান্স: প্রথমে কম ডেটা লোড হয়, ফলে প্রথম লোডিং দ্রুত হয়, কিন্তু সম্পর্কিত ডেটা অ্যাক্সেস করার সময় অতিরিক্ত ডেটাবেস কুয়েরি প্রয়োজন হতে পারে।

উদাহরণ:

from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Parent(Base):
    __tablename__ = 'parents'
    id = Column(Integer, primary_key=True)
    name = Column(String)

class Child(Base):
    __tablename__ = 'children'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    parent_id = Column(Integer, ForeignKey('parents.id'))

    parent = relationship("Parent", lazy='select')  # Lazy Loading

# ইঞ্জিন এবং সেশন তৈরি
engine = create_engine('sqlite:///example.db', echo=True)
Session = sessionmaker(bind=engine)
session = Session()

# Parent এবং Child অবজেক্ট তৈরি করা
parent = Parent(name="John Doe")
child = Child(name="Jane Doe", parent=parent)

# ডেটাবেসে সেভ করা
session.add(parent)
session.commit()

# Parent অবজেক্টে সম্পর্কিত Child অবজেক্ট অ্যাক্সেস করা
parent_from_db = session.query(Parent).first()
print(parent_from_db.name)  # Parent নাম প্রিন্ট হবে

# এখানে Child অবজেক্ট সম্পর্কিত ডেটা তখনই লোড হবে যখন parent_from_db.child অ্যাক্সেস করা হবে
print(parent_from_db.child.name)  # Lazy loading এর মাধ্যমে Child অবজেক্ট লোড হবে

এখানে, Parent অবজেক্টের সাথে সম্পর্কিত Child অবজেক্টকে Lazy Loading পদ্ধতিতে লোড করা হচ্ছে। যখন parent_from_db.child অ্যাক্সেস করা হবে, তখনই সম্পর্কিত Child অবজেক্টটি ডেটাবেস থেকে লোড হবে।


Eager Loading

Eager Loading হল এমন একটি কৌশল, যেখানে সম্পর্কিত ডেটা প্রথম থেকেই লোড হয়ে যায়। যখন আপনি মূল অবজেক্ট (Parent) লোড করেন, তখন সম্পর্কিত অবজেক্টগুলোও একই সাথে লোড হয়ে যায়। এটি সম্পর্কিত ডেটা লোড করার জন্য একাধিক কুয়েরি চালাতে বাধা দেয় এবং ডেটাবেস থেকে সম্পর্কিত সব ডেটা একসাথে নিয়ে আসে।

বৈশিষ্ট্য:

  • পুরো ডেটা লোডিং: মূল অবজেক্টের সাথে সম্পর্কিত সমস্ত অবজেক্ট একই সাথে লোড করা হয়।
  • পারফরম্যান্স: এটি একাধিক কুয়েরি চালানোর প্রয়োজনীয়তা কমায়, তবে অনেক ডেটা একসাথে লোড হওয়ায় এটি মেমোরি খরচ বাড়াতে পারে।

উদাহরণ:

from sqlalchemy.orm import joinedload

# Eager Loading এর জন্য relationship পদ্ধতি ব্যবহার করা
parent_from_db = session.query(Parent).options(joinedload(Parent.child)).first()

# এখন Parent এর সাথে সম্পর্কিত Child অবজেক্টও একসাথে লোড হয়ে যাবে
print(parent_from_db.name)
print(parent_from_db.child.name)  # Eager loading এর মাধ্যমে Child অবজেক্ট লোড হবে

এখানে, joinedload পদ্ধতি ব্যবহার করে Parent অবজেক্টের সাথে সম্পর্কিত Child অবজেক্ট Eager Loading পদ্ধতিতে লোড করা হয়েছে। এই কৌশলে একসাথে ডেটাবেস থেকে Parent এবং Child উভয় অবজেক্টই লোড হবে।


Lazy Loading বনাম Eager Loading এর পার্থক্য

বৈশিষ্ট্যLazy LoadingEager Loading
লোডিং সময়সম্পর্কিত অবজেক্ট লোড হয় প্রয়োজনের সময়সম্পর্কিত সব অবজেক্ট একসাথে লোড হয়
পারফরম্যান্সপ্রথম লোডিং দ্রুত কিন্তু অতিরিক্ত কুয়েরি হতে পারেএকাধিক কুয়েরি কমিয়ে দেয়, তবে অতিরিক্ত মেমোরি ব্যবহার হতে পারে
ডেটাবেস কুয়েরিপ্রাথমিকভাবে মূল অবজেক্ট লোড হয়, পরে সম্পর্কিত ডেটা লোড হয়সম্পর্কিত সব ডেটা একসাথে ডেটাবেস থেকে লোড হয়
ব্যবহারছোট, একক সম্পর্কিত ডেটা লোড করার জন্য উপযুক্তসম্পর্কিত সব ডেটা একসাথে লোড করতে উপযুক্ত

কোন পরিস্থিতিতে কোন পদ্ধতি ব্যবহার করবেন?

  • Lazy Loading ব্যবহার করুন যদি:
    • আপনি জানেন না যে আপনার কিভাবে সম্পর্কিত ডেটা ব্যবহার হবে এবং আপনি ডেটাবেসে অতিরিক্ত কুয়েরি পাঠাতে চান না।
    • আপনি ছোট বা নির্দিষ্ট পরিমাণে সম্পর্কিত ডেটা লোড করতে চান।
  • Eager Loading ব্যবহার করুন যদি:
    • আপনি নিশ্চিত যে আপনার প্রধান অবজেক্টের সাথে সম্পর্কিত ডেটা প্রয়োজন হবে এবং একাধিক কুয়েরি না চালিয়ে একসাথে সব ডেটা লোড করতে চান।
    • একাধিক সম্পর্কিত ডেটা একযোগে লোড করা দরকার।

সারাংশ

Lazy Loading এবং Eager Loading হল ডেটাবেস থেকে সম্পর্কিত ডেটা লোড করার দুটি কৌশল। Lazy Loading কেবল তখনই সম্পর্কিত ডেটা লোড করে যখন সেটি প্রয়োজন হয়, তবে Eager Loading সম্পর্কিত সমস্ত ডেটা একসাথে লোড করে। আপনি প্রয়োজনে এই দুটি পদ্ধতির মধ্যে যেকোনো একটি ব্যবহার করতে পারেন, যা আপনার অ্যাপ্লিকেশন এবং পারফরম্যান্সের প্রয়োজন অনুযায়ী উপযুক্ত।

Content added By

Joins এবং Complex Query তৈরির কৌশল

339

SQLAlchemy ORM এবং Core ব্যবহার করে Joins এবং Complex Queries তৈরি করা ডেটাবেসের সাথে কাজ করার একটি গুরুত্বপূর্ণ দিক। এই কৌশলগুলো আপনাকে একাধিক টেবিলের মধ্যে সম্পর্ক তৈরি করতে এবং ডেটাবেসে জটিল অনুসন্ধান সম্পাদন করতে সাহায্য করবে।


Joins কী এবং SQLAlchemy তে কীভাবে কাজ করে?

Joins ডেটাবেসের মধ্যে দুটি বা তার বেশি টেবিলের মধ্যে সম্পর্ক স্থাপন করে। বিভিন্ন ধরনের Joins রয়েছে:

  • INNER JOIN: দুটি টেবিলের মধ্যে মিল থাকা রেকর্ডগুলোকে ফেরত দেয়।
  • LEFT OUTER JOIN: প্রথম টেবিলের সব রেকর্ড এবং মিল পাওয়া রেকর্ডগুলো ফেরত দেয়।
  • RIGHT OUTER JOIN: দ্বিতীয় টেবিলের সব রেকর্ড এবং মিল পাওয়া রেকর্ডগুলো ফেরত দেয়।
  • FULL OUTER JOIN: দুটি টেবিলের সব রেকর্ড ফেরত দেয়, মিল পাওয়া রেকর্ডগুলোসহ।

SQLAlchemy তে Join কার্যকর করতে, আপনাকে relationship() বা join() ফাংশন ব্যবহার করতে হবে। ORM এবং Core উভয় ক্ষেত্রেই এটি ব্যবহার করা সম্ভব।


SQLAlchemy ORM এ Joins ব্যবহার করা

SQLAlchemy ORM এর মাধ্যমে relationships ব্যবহার করে টেবিলের মধ্যে সম্পর্ক স্থাপন করা যায়। নিচে One-to-Many সম্পর্কের জন্য Join এর উদাহরণ দেখানো হলো:

উদাহরণ:

ধরা যাক, আমাদের দুটি টেবিল User এবং Post আছে, যেখানে One-to-Many সম্পর্ক রয়েছে (একজন ইউজারের অনেক পোস্ট থাকতে পারে)।

from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# Base ক্লাস তৈরি
Base = declarative_base()

# User টেবিল
class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    posts = relationship('Post', back_populates='user')  # Relationship with Post

# Post টেবিল
class Post(Base):
    __tablename__ = 'posts'
    id = Column(Integer, primary_key=True)
    title = Column(String)
    content = Column(String)
    user_id = Column(Integer, ForeignKey('users.id'))  # Foreign Key to User table
    user = relationship('User', back_populates='posts')  # Relationship with User

# SQLite ডেটাবেসের জন্য ইঞ্জিন তৈরি
engine = create_engine('sqlite:///example.db')

# টেবিল তৈরি
Base.metadata.create_all(engine)

# Session তৈরি
Session = sessionmaker(bind=engine)
session = Session()

# কিছু ডেটা ইনসার্ট করা
new_user = User(name="Alice")
session.add(new_user)
session.commit()

new_post1 = Post(title="Post 1", content="Content 1", user_id=new_user.id)
new_post2 = Post(title="Post 2", content="Content 2", user_id=new_user.id)
session.add(new_post1)
session.add(new_post2)
session.commit()

Joins এর মাধ্যমে ডেটা ফেচিং

# Join ব্যবহার করে ইউজারের সাথে পোস্ট ফেচ করা
users_with_posts = session.query(User).join(Post).filter(Post.user_id == User.id).all()

for user in users_with_posts:
    print(user.name)
    for post in user.posts:
        print(f" - {post.title}")

এখানে, session.query(User).join(Post) ব্যবহার করে User এবং Post টেবিলের মধ্যে INNER JOIN করা হয়েছে, যেখানে Post.user_id এবং User.id মিলে যাচ্ছে।


SQLAlchemy Core এ Joins ব্যবহার করা

SQLAlchemy Core ব্যবহার করে join() ফাংশন ব্যবহার করে একই ফলাফল পাওয়া যায়।

from sqlalchemy import Table, MetaData, create_engine, select

# টেবিল ডিফাইন করা
metadata = MetaData()
users = Table('users', metadata,
              Column('id', Integer, primary_key=True),
              Column('name', String))

posts = Table('posts', metadata,
              Column('id', Integer, primary_key=True),
              Column('title', String),
              Column('content', String),
              Column('user_id', Integer, ForeignKey('users.id')))

# ইঞ্জিন তৈরি
engine = create_engine('sqlite:///example.db')

# ডেটাবেসে সংযোগ এবং জয়েন কোয়েরি তৈরি
with engine.connect() as conn:
    query = select([users.c.name, posts.c.title]).select_from(users.join(posts))
    result = conn.execute(query)

    for row in result:
        print(row)

এখানে users.join(posts) ব্যবহার করে INNER JOIN সম্পন্ন করা হয়েছে এবং select() ফাংশন ব্যবহার করে ডেটা রিট্রিভ করা হয়েছে।


Complex Queries (জটিল কোয়েরি) তৈরির কৌশল

SQLAlchemy তে Complex Queries তৈরি করার জন্য একাধিক টেবিলের উপর Joins, Filters, Aggregates, Group By, Having, Subqueries, Window Functions ইত্যাদি ব্যবহার করা যায়। এই কৌশলগুলি ডেটাবেসের জটিল অপারেশন সম্পাদন করতে সহায়ক।

উদাহরণ: Group By এবং Aggregate Functions

from sqlalchemy import func

# ডেটাবেসে Group By এবং Aggregate Function ব্যবহার করা
query = session.query(User.name, func.count(Post.id).label('post_count')).join(Post).group_by(User.name).all()

for row in query:
    print(f"User: {row.name}, Posts: {row.post_count}")

এখানে, func.count(Post.id) ব্যবহার করে COUNT অ্যাগ্রিগেট ফাংশন ব্যবহার করা হয়েছে এবং group_by(User.name) দিয়ে গ্রুপ করা হয়েছে। এটি প্রতিটি ইউজারের পোস্টের সংখ্যা ফিরিয়ে দেয়।


উদাহরণ: Subquery

# Subquery ব্যবহার করা
subquery = session.query(Post.user_id, func.count(Post.id).label('post_count')).group_by(Post.user_id).subquery()

query = session.query(User.name, subquery.c.post_count).join(subquery, subquery.c.user_id == User.id)
for row in query:
    print(f"User: {row.name}, Posts: {row.post_count}")

এখানে, subquery তৈরি করা হয়েছে যা Post টেবিলের প্রতি ইউজারের পোস্টের সংখ্যা গণনা করে এবং তারপর মূল কোয়েরির মধ্যে এটি যুক্ত করা হয়েছে।


সারাংশ

Joins এবং Complex Queries SQLAlchemy তে ডেটাবেসের সাথে কাজ করার একটি শক্তিশালী কৌশল। Joins ব্যবহার করে একাধিক টেবিলের মধ্যে সম্পর্ক স্থাপন করা যায় এবং Complex Queries এর মাধ্যমে Group By, Aggregate Functions, Subqueries, এবং Window Functions ব্যবহার করে জটিল ডেটা বিশ্লেষণ করা যায়। SQLAlchemy ORM এবং Core উভয়ই এই কাজগুলোকে সহজ এবং কার্যকর করে তোলে, যা ডেটাবেস অপারেশনকে আরও নমনীয় ও পারফরম্যান্স-ভিত্তিক করে তোলে।

Content added By
Promotion

Are you sure to start over?

Loading...