Skip to content

Instantly share code, notes, and snippets.

@miguelgarcia
Last active January 29, 2024 13:08
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save miguelgarcia/313be49c59c1ffad391eb10ef169d73f to your computer and use it in GitHub Desktop.
Save miguelgarcia/313be49c59c1ffad391eb10ef169d73f to your computer and use it in GitHub Desktop.
Python: factoryboy + sqlalchemy. SubFactory and RelatedFactory example
# factories
class CategoryFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta:
model = models.Category
sqlalchemy_session = db.session
sqlalchemy_session_persistence = 'commit'
name = factory.Sequence(lambda n: u'Category %d' % n)
class CompanyFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta:
model = models.Company
sqlalchemy_session = db.session
sqlalchemy_session_persistence = 'commit'
name = factory.Sequence(lambda n: u'Company %d' % n)
class ProductFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta:
model = models.Product
sqlalchemy_session = db.session
sqlalchemy_session_persistence = 'commit'
name = factory.Sequence(lambda n: u'Name %d' % n)
maker = factory.SubFactory(CompanyFactory)
category1 = factory.RelatedFactory(ProductCategoryFactory, 'product')
category2 = factory.RelatedFactory(ProductCategoryFactory, 'product')
class ProductCategoryFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta:
model = models.ProductCategoryFactory
sqlalchemy_session = db.session
sqlalchemy_session_persistence = 'commit'
category = factory.SubFactory(CategoryFactory)
product = factory.SubFactory(ProductFactory)
# SubFactory:
# Product has one maker that is a Company
# Reference from product to company, then SubFactory in ProductFactory
# RelatedFactory:
# Each product is associated with multiple categories
# for each realated category RelatedFactory creates a ProductCategoryFactory
# and sets prc.product to the product being built
# Example:
# ProductFactory().create() creates
# - a product, lets name it P
# - a Company and sets it as the product maker, because of `maker = factory.SubFactory(CompanyFactory)`
# - 2 ProductCategoryFactory with .product = P, because of `factory.RelatedFactory(ProductCategoryFactory, 'product')`
# - 2 Categories, one for each ProductCategoryFactory, because of `category = factory.SubFactory(CategoryFactory)`
# models
class Category(db.Model):
__tablename__ = "category"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.Unicode(255), nullable=False, unique=True)
products = db.relationship("Product", secondary="product_category")
class Company(db.Model):
__tablename__ = "company"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.Unicode(255), nullable=False, unique=True)
products = db.relationship("Product", back_populates="maker")
class Product(db.Model):
__tablename__ = "product"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.Unicode(255), nullable=False, unique=True)
maker_id = db.Column(db.Integer, db.ForeignKey('company.id'), nullable=False)
maker = db.relationship("Company", back_populates="products")
categories = db.relationship("Category", secondary="product_category")
class ProductCategory(db.Model):
__tablename__ = "product_category"
product_id = db.Column(db.Integer, db.ForeignKey('product.id'), primary_key=True)
category_id = db.Column(db.Integer, db.ForeignKey('category.id'), primary_key=True)
product = db.relationship("Product", backref=db.backref("product_category", cascade="all, delete-orphan"))
category = db.relationship("Category", backref=db.backref("product_category", cascade="all, delete-orphan"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment