Implementasi Polymorphic Inheritance di SQLAlchemy Model (Join Table)
Pada implementasi database terkadang diperlukan sebuah tabel yang merupakan keturunan table lain contoh table users
yang memiliki keturunan table employee
dan table client
, maka dalam implementasinya bisa dengan membuat struktur:
table users
-------------------------
| Field | Type |
------------------------|
| id | int(11) |
| name | varchar(50) |
| email | varchar(50) |
| type | varchar(10) |
-------------------------
table employee
----------------------------
| Field | Type |
---------------------------|
| id | int(11) |
| department | varchar(50) |
----------------------------
table client
-----------------------------
| Field | Type |
-----------------------------
| id | int(11) |
| address | varchar(50) |
-----------------------------
Dengan struktur table seperti itu maka bisa di representasikan menjadi model sqlalchemy menjadi seperti berikut:
preparing sqlalchemy connection, session, database dan base mode.
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
engine = create_engine('sqlite:///:memory')
Base = declarative_base()
Session = sessionmaker(bind=engine)
session = Session()Base = declarative_base()
model Users
class Users(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
name = Column(String)
email = Column(String)
# digunakan sebagai discriminator
type = Column(String)
__mapper_args__ = {
# jika type pada parent merupakan `user` maka object akan
# menjadi instance dari class ini
'polymorphic_identity': 'user',
'polymorphic_on': type # Parent model harus mengimplementasi ini
}
def __init__(self, name, email, _type='user'):
self.name = name
self.email = email
self.type = _type
def __repr__(self):
return "<Users (name='%s', email='%s')>" % (self.name, self.email)
model employee
class Employee(Users):
__tablename__ = "employee"
id = Column(None, ForeignKey("users.id"), primary_key=True)
department = Column(String)
__mapper_args__ = {
# jika type pada parent merupakan `employee` maka object akan
# menjadi instance dari class ini
'polymorphic_identity': 'employee'
}
def __init__(self, name, email, department):
super().__init__(name, email, 'employee')
self.department = department
def __repr__(self):
return "<Employee (name='%s', email='%s', department='%s')>" % (
self.name, self.email, self.department
)
model client
class Client(Users):
__tablename__ = "client"
id = Column(None, ForeignKey("users.id"), primary_key=True)
address = Column(String)
__mapper_args__ = {
# jika type pada parent merupakan `client` maka object akan
# menjadi instance dari class ini
'polymorphic_identity': 'client'
}
def __init__(self, name, email, address):
super().__init__(name, email, "client")
self.address = address
def __repr__(self):
return "<Client (name='%s', email='%s', address='%s')>" % (
self.name, self.email, self.address
)
Saatnya testing.
# create table
Base.metadata.create_all(engine)
user = Users("faisalburhanudin", "faisalburhanudin@hotmail.com")
session.add(user)
print(session.query(Users).all())
employee = Employee("gogil", "gogil@mail.com", "hrd")
session.add(employee)
print(session.query(Employee).all())
client = Client("client_name", "client@mail.com", "Klaten")
session.add(client)
session.add(client)
print(session.query(Client).all())
Written on November 20, 2016