def test_id(app_empty): # This test doesn't pass because the "set" events to the # relationships won't be triggered when the foreign keys are set. # It might be possible to pass this test with before_flush(). # Useful links about before_flush(): # https://docs.sqlalchemy.org/en/14/orm/session_events.html#persistence-events # https://stackoverflow.com/questions/36731020/sqlalchemy-orm-event-hook-for-attribute-persisted app = app_empty # # +---------+ +--------+ # | | --(child)--> | | # | parent1 | | | child1 | # | | <-(parent)-- | | # +---------+ +--------+ # type_ = ProductType(name="robot") parent1 = Product(product_id=1, name="parent1", type_=type_) child1 = Product(product_id=2, name="child1", type_=type_) relation_type_parent = ProductRelationType(type_id=1, name="parent") relation_type_child = ProductRelationType(type_id=2, name="child") relation_type_parent.reverse = relation_type_child relation_parent1_to_child1 = ProductRelation(type_id=2, self_product_id=1, other_product_id=2) with app.app_context(): sa.session.add(parent1) sa.session.add(child1) sa.session.add(relation_type_parent) sa.session.add(relation_parent1_to_child1) sa.session.flush() sa.session.commit() with app.app_context(): parent1 = Product.query.filter_by(name="parent1").first() child1 = Product.query.filter_by(name="child1").first() assert 1 == len(parent1.relations) assert 1 == len(child1.relations) assert "child" == parent1.relations[0].type_.name assert "parent" == child1.relations[0].type_.name assert child1 is parent1.relations[0].other assert parent1 is child1.relations[0].other assert parent1.relations[0] is child1.relations[0].reverse assert parent1.relations[0].reverse is child1.relations[0]
def test_self_reverse_type(app_empty, perm): app = app_empty # # +----------+ +----------+ # | | --(sibling)--> | | # | sibling1 | | | sibling2 | # | | <-(sibling)-- | | # +----------+ +----------+ # type_ = ProductType(name="robot") sibling1 = Product(name="sibling1", type_=type_) sibling2 = Product(name="sibling2", type_=type_) relation_type_sibling = ProductRelationType(name="sibling") relation_type_sibling.reverse = relation_type_sibling relation_sibling1_to_sibling2 = ProductRelation() # set 'type_', 'self_', 'other' in different orders # each triggers an event in which a reverse is automatically set for p in perm: if p == 1: relation_sibling1_to_sibling2.type_ = relation_type_sibling elif p == 2: relation_sibling1_to_sibling2.self_ = sibling1 elif p == 3: relation_sibling1_to_sibling2.other = sibling2 with app.app_context(): sa.session.add(sibling1) sa.session.commit() with app.app_context(): sibling1 = Product.query.filter_by(name="sibling1").first() sibling2 = Product.query.filter_by(name="sibling2").first() assert 1 == len(sibling1.relations) assert 1 == len(sibling2.relations) assert "sibling" == sibling1.relations[0].type_.name assert "sibling" == sibling2.relations[0].type_.name assert sibling1.relations[0].type_ is sibling2.relations[0].type_ assert sibling2 is sibling1.relations[0].other assert sibling1 is sibling2.relations[0].other assert sibling1.relations[0] is sibling2.relations[0].reverse assert sibling1.relations[0].reverse is sibling2.relations[0]
def test_attach_to_self(app_empty): app = app_empty # # +---------+ +--------+ # | | --(child)--> | | # | parent1 | | | child1 | # | | <-(parent)-- | | # +---------+ +--------+ # type_ = ProductType(name="robot") parent1 = Product(product_id=1, name="parent1", type_=type_) child1 = Product(product_id=2, name="child1", type_=type_) relation_type_parent = ProductRelationType(type_id=1, name="parent") relation_type_child = ProductRelationType(type_id=2, name="child") relation_type_parent.reverse = relation_type_child relation_parent1_to_child1 = ProductRelation(type_=relation_type_child, other=child1) parent1.relations = [relation_parent1_to_child1] with app.app_context(): sa.session.add(parent1) sa.session.add(child1) sa.session.add(relation_type_parent) sa.session.add(relation_parent1_to_child1) sa.session.flush() sa.session.commit() with app.app_context(): parent1 = Product.query.filter_by(name="parent1").first() child1 = Product.query.filter_by(name="child1").first() assert 1 == len(parent1.relations) assert 1 == len(child1.relations) assert "child" == parent1.relations[0].type_.name assert "parent" == child1.relations[0].type_.name assert child1 is parent1.relations[0].other assert parent1 is child1.relations[0].other assert parent1.relations[0] is child1.relations[0].reverse assert parent1.relations[0].reverse is child1.relations[0]
def app(app_empty): y = app_empty # +--------+ # --(child)--> | | # | | child1 | # +---------+ <-(parent)-- | | # | | +--------+ # | parent1 | # | | +--------+ # +---------+ --(child)--> | | # | | child2 | # <-(parent)-- | | # +--------+ type_ = ProductType(name="robot") parent1 = Product(name="parent1", type_=type_) child1 = Product(name="child1", type_=type_) child2 = Product(name="child2", type_=type_) relation_type_parent = ProductRelationType(name="parent") relation_type_child = ProductRelationType(name="child") relation_type_parent.reverse = relation_type_child # parent1 --(child)--> child1 relation_parent1_to_child1 = ProductRelation() relation_parent1_to_child1.type_ = relation_type_child relation_parent1_to_child1.self_ = parent1 relation_parent1_to_child1.other = child1 ## the reverse relation child1 --(parent)--> parent1 will be ## automatically set # parent1 --(child)--> child2 relation_parent1_to_child2 = ProductRelation() relation_parent1_to_child2.type_ = relation_type_child relation_parent1_to_child2.self_ = parent1 relation_parent1_to_child2.other = child2 ## the reverse relation child2 --(parent)--> parent1 will be ## automatically set # commit with y.app_context(): sa.session.add(parent1) sa.session.commit() yield y
def app(app_empty): y = app_empty # # +--------+ +-------+ # | | --(reverse)-> | | # | parent | | child | # | | <-(reverse)-- | | # +--------+ +-------+ # # # +------- -+ # | | --(reverse)-+ # | sibling | | # | | <-----------+ # +------ --+ # parent = ProductRelationType(name="parent") child = ProductRelationType(name="child") parent.reverse = child assert child.reverse == parent sibling = ProductRelationType(name="sibling") sibling.reverse = sibling # commit with y.app_context(): sa.session.add(parent) sa.session.add(sibling) sa.session.commit() yield y
def test_permutations(app_empty, perm): app = app_empty # # +---------+ +--------+ # | | --(child)--> | | # | parent1 | | | child1 | # | | <-(parent)-- | | # +---------+ +--------+ # type_ = ProductType(name="robot") parent1 = Product(name="parent1", type_=type_) child1 = Product(name="child1", type_=type_) relation_type_parent = ProductRelationType(name="parent") relation_type_child = ProductRelationType(name="child") relation_type_parent.reverse = relation_type_child relation_type_child.reverse = relation_type_parent relation_parent1_to_child1 = ProductRelation() # set 'type_', 'self_', 'other' in different orders # each triggers an event in which a reverse is automatically set for p in perm: if p == 1: relation_parent1_to_child1.type_ = relation_type_child elif p == 2: relation_parent1_to_child1.self_ = parent1 elif p == 3: relation_parent1_to_child1.other = child1 with app.app_context(): sa.session.add(parent1) sa.session.commit() with app.app_context(): parent1 = Product.query.filter_by(name="parent1").first() child1 = Product.query.filter_by(name="child1").first() assert 1 == len(parent1.relations) assert 1 == len(child1.relations) assert "child" == parent1.relations[0].type_.name assert "parent" == child1.relations[0].type_.name assert child1 is parent1.relations[0].other assert parent1 is child1.relations[0].other assert parent1.relations[0] is child1.relations[0].reverse assert parent1.relations[0].reverse is child1.relations[0]
def test_column(app_empty): app = app_empty with app.app_context(): model = ProductRelationType( name="parent", indef_article="a", singular="parent", plural="parents", ) sa.session.add(model) sa.session.commit() assert model.type_id type_id = model.type_id with app.app_context(): model = ProductRelationType.query.filter_by(type_id=type_id).one() assert model.type_id == type_id assert model.name == "parent" assert model.indef_article == "a" assert model.singular == "parent" assert model.plural == "parents"