Birçok İlişkiye

Many to Many relationshipiki tablo arasında, her tablonun birincil anahtarından bir tane olmak üzere iki yabancı anahtara sahip olacak şekilde bir ilişkilendirme tablosu eklenerek elde edilir. Ayrıca, iki tabloyla eşleşen sınıflar, diğer ilişkilendirme tablolarının nesnelerinin bir koleksiyonunu, ilişkinin ikincil özniteliği () işlevi olarak atanan bir özniteliğe sahiptir.

Bu amaçla, departman ve çalışan olmak üzere iki tablo içeren bir SQLite veritabanı (mycollege.db) oluşturacağız. Burada bir çalışanın birden fazla departmanın parçası olduğunu ve bir departmanın birden fazla çalışanı olduğunu varsayıyoruz. Bu çoktan çoğa bir ilişki oluşturur.

Departman ve çalışan tablosuna eşlenen Çalışan ve Departman sınıflarının tanımı aşağıdaki gibidir -

from sqlalchemy import create_engine, ForeignKey, Column, Integer, String
engine = create_engine('sqlite:///mycollege.db', echo = True)
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
from sqlalchemy.orm import relationship

class Department(Base):
   __tablename__ = 'department'
   id = Column(Integer, primary_key = True)
   name = Column(String)
   employees = relationship('Employee', secondary = 'link')
   
class Employee(Base):
   __tablename__ = 'employee'
   id = Column(Integer, primary_key = True)
   name = Column(String)
   departments = relationship(Department,secondary='link')

Şimdi bir Link sınıfı tanımlıyoruz. Bağlantı tablosuna bağlıdır ve sırasıyla departman ve çalışan tablosunun birincil anahtarlarına atıfta bulunan departman_id ve çalışan_kimliği özniteliklerini içerir.

class Link(Base):
   __tablename__ = 'link'
   department_id = Column(
      Integer, 
      ForeignKey('department.id'), 
      primary_key = True)

employee_id = Column(
   Integer, 
   ForeignKey('employee.id'), 
   primary_key = True)

Burada, Departman sınıfının Çalışan sınıfıyla ilgili çalışan özniteliğine sahip olduğunu not etmeliyiz. İlişki işlevinin ikincil niteliğine, değeri olarak bir bağlantı atanır.

Benzer şekilde, Çalışan sınıfı, Departman sınıfıyla ilgili departments özniteliğine sahiptir. İlişki işlevinin ikincil niteliğine, değeri olarak bir bağlantı atanır.

Aşağıdaki ifade yürütüldüğünde bu üç tablonun tümü oluşturulur -

Base.metadata.create_all(engine)

Python konsolu aşağıdaki CREATE TABLE sorgularını yayınlar -

CREATE TABLE department (
   id INTEGER NOT NULL,
   name VARCHAR,
   PRIMARY KEY (id)
)

CREATE TABLE employee (
   id INTEGER NOT NULL,
   name VARCHAR,
   PRIMARY KEY (id)
)

CREATE TABLE link (
   department_id INTEGER NOT NULL,
   employee_id INTEGER NOT NULL,
   PRIMARY KEY (department_id, employee_id),
   FOREIGN KEY(department_id) REFERENCES department (id),
   FOREIGN KEY(employee_id) REFERENCES employee (id)
)

Bunu, aşağıda verilen ekran görüntülerinde gösterildiği gibi SQLiteStudio kullanarak mycollege.db'yi açarak kontrol edebiliriz -

Daha sonra, aşağıda gösterildiği gibi, Department sınıfının üç nesnesini ve Employee sınıfının üç nesnesini oluşturuyoruz -

d1 = Department(name = "Accounts")
d2 = Department(name = "Sales")
d3 = Department(name = "Marketing")

e1 = Employee(name = "John")
e2 = Employee(name = "Tony")
e3 = Employee(name = "Graham")

Her tablonun append () yöntemine sahip bir koleksiyon özelliği vardır. Employee nesneleri, Department nesnesinin Employees koleksiyonuna ekleyebiliriz. Benzer şekilde, Employee nesnelerinin departments collection özniteliğine Department nesneleri ekleyebiliriz.

e1.departments.append(d1)
e2.departments.append(d3)
d1.employees.append(e3)
d2.employees.append(e2)
d3.employees.append(e1)
e3.departments.append(d2)

Şimdi tek yapmamız gereken, bir oturum nesnesi oluşturmak, tüm nesneleri ona eklemek ve aşağıda gösterildiği gibi değişiklikleri uygulamak -

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)
session = Session()
session.add(e1)
session.add(e2)
session.add(d1)
session.add(d2)
session.add(d3)
session.add(e3)
session.commit()

Python konsolunda aşağıdaki SQL ifadeleri yayınlanacaktır -

INSERT INTO department (name) VALUES (?) ('Accounts',)
INSERT INTO department (name) VALUES (?) ('Sales',)
INSERT INTO department (name) VALUES (?) ('Marketing',)
INSERT INTO employee (name) VALUES (?) ('John',)
INSERT INTO employee (name) VALUES (?) ('Graham',)
INSERT INTO employee (name) VALUES (?) ('Tony',)
INSERT INTO link (department_id, employee_id) VALUES (?, ?) ((1, 2), (3, 1), (2, 3))
INSERT INTO link (department_id, employee_id) VALUES (?, ?) ((1, 1), (2, 2), (3, 3))

Yukarıdaki işlemlerin etkisini kontrol etmek için SQLiteStudio kullanın ve departman, çalışan ve bağlantı tablolarındaki verileri görüntüleyin -

Verileri görüntülemek için aşağıdaki sorgu ifadesini çalıştırın -

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)
session = Session()

for x in session.query( Department, Employee).filter(Link.department_id == Department.id, 
   Link.employee_id == Employee.id).order_by(Link.department_id).all():
   print ("Department: {} Name: {}".format(x.Department.name, x.Employee.name))

Örneğimizde doldurulan verilere göre, çıktı aşağıdaki gibi görüntülenecektir -

Department: Accounts Name: John
Department: Accounts Name: Graham
Department: Sales Name: Graham
Department: Sales Name: Tony
Department: Marketing Name: John
Department: Marketing Name: Tony