Şu üç teknolojiyi bir arada kullanıyorsanız:
- Python
- SQLAlchemy (zaten Python‘suz olmaz 🙂 )
- PostgreSQL
ve benim gibi, önce model class’ı yazmak yerine veri tabanı tablolarını oluşturmayı seviyorsanız. Model class’larını oluşturacak bir reverse engineering scripti zorunlu oluyor. Özellikle de büyük projelerde her bir modeli tek tek yazmak tam bir işkence ve hata yapma ihtimali çok yüksek. Oysa veri tabanı tabloları ER diagramında oluşturulmalı diye düşünüyorum. Bu çalışma şekliye bir reverse engineering programı bulamadım.
İşte bu ihtiyaçtan bir python script yazdım ve kullanmaya başladım. Script, SQLAlchemy için PostgreSQL tablolarını okuyor, İlişkleri sorguluyor ve model sınıflarını üretiyor. Her bir sınıf için to_json yordamı da bonus 🙂
Scripti şurdan edinebilirsiniz.
https://github.com/aerkanc/SAModelGenerator
Kullanımı ise basit
model-generator.py -host [DBSERVER] -user [DBUSER] -pass [DBUSER'S PASSWORD] -db [DBNAME] -file [OUTPUT FILE PATH] -sch [SCHEME (default=public)]
Örnek vermek gerekirse:
model-generator.py -host "localhost" -user "mydbusername" -pass "mydbuserpassword" -db "mydb" -file "/home/myusername/Workspace/Python/MyProject/Model/model.py"
Ben şimdiye kadar üç projede kullandım. Karşılaştığım sorunları düzelttim. Eğer yeni bir hata bulursanız, düzeltin/raporlayın/commit request yapın/ fork yapın düzeltin.
Örnek
Bir product, brand ilişkisi üzerinden örnek vermek gerekirse, sonuç olarak ortaya çıkacak model sınıfları şöyle olacaktır:
class Product(Base): __tablename__ = u'product' #column definitions id = Column(BIGINT(), Sequence('product_id_seq'), primary_key=True, nullable=False) brand = Column(BIGINT(), ForeignKey('brand.id')) product = Column(VARCHAR(length=255)) slug = Column(VARCHAR(length=255)) created_at = Column(TIMESTAMP()) is_active = Column(BOOLEAN(), server_default=text('false')) activated_at = Column(TIMESTAMP()) category = Column(BIGINT(), ForeignKey('category.id')) #relation definitions: many to one with backref (also takes care of one to many) ProductBrand = relationship('Brand', primaryjoin='Product.brand == Brand.id') ProductCategory = relationship('Category', primaryjoin='Product.category == Category.id') def to_json(self): obj = { 'id': self.id, 'brand': self.brand, 'product': self.product, 'slug': self.slug, 'created_at': self.created_at.strftime('%a, %d %b %Y %H:%M:%S +0000') if self.created_at else None, 'is_active': self.is_active, 'activated_at': self.activated_at.strftime('%a, %d %b %Y %H:%M:%S +0000') if self.activated_at else None, 'category': self.category, } return json.dumps(obj)
class Brand(Base): __tablename__ = u'brand' #column definitions id = Column(BIGINT(), Sequence('brand_id_seq'), primary_key=True, nullable=False) brand = Column(VARCHAR(length=255)) slug = Column(VARCHAR(length=255)) created_at = Column(TIMESTAMP()) def to_json(self): obj = { 'id': self.id, 'brand': self.brand, 'slug': self.slug, 'created_at': self.created_at.strftime('%a, %d %b %Y %H:%M:%S +0000') if self.created_at else None, } return json.dumps(obj)