Ich verwende das SQLalchemy association-object Muster (http://docs.sqlalchemy.org/en/rel_1_1/orm/basic_relationships.html#association-object) für drei Modellklassen.Wie wird Factory Boy zum Testen von SQLalchemy-Assoziationsobjektmodellen verwendet?
Grundlegende Beziehung ist auf der linken Seite ein Benutzer kann zu mehreren Organisationen gehören. Ich speichere zusätzliche benutzerorganisationsrelevante Daten in der Assoziationsobjektklasse. Dann ordnet die Assoziationsobjektklasse der Organisation eine Viele-zu-Eins-Beziehung zu.
Von SQLAlchemy Punkt funktioniert die Beziehung gut. Das Problem ist, dies mit Fabrikjungen zu testen, hat sich als schwierig erwiesen und führt immer zu einem Fehler .
Im Folgenden sind die drei Modelle für die Objekt-Beziehung Assoziation, wo Benutzer Elternteil und das Kind ist Organisation:
class MemberOrgsAssoc(Model):
"""The left side of the relationship maps a User as a one-to-many to
Organizations. User-Organization relevant data is stored in
this association-object table. Then, there is a one-to-many from
this association-object table to the Organization table. """
__tablename__ = 'member_orgs'
member_id = Column(db.Integer, db.ForeignKey("users.id"), primary_key=True)
org_id = Column(db.Integer, db.ForeignKey("organizations.id"), primary_key=True)
manager_id = Column(db.Integer, db.ForeignKey("users.id"))
org_title = Column(db.Unicode(50))
organization = relationship("Organization", back_populates="members")
member = relationship("User", back_populates="organizations",
foreign_keys=[member_id])
manager = relationship("User", back_populates="subordinates",
foreign_keys=[manager_id])
class User(SurrogatePK, Model):
"""A user of the app."""
__tablename__ = 'users'
username = Column(db.Unicode(80), unique=True, nullable=False)
organizations = relationship("MemberOrgsAssoc", back_populates="member",
primaryjoin = "member_orgs.c.member_id == User.id",
lazy="dynamic")
subordinates = relationship("MemberOrgsAssoc", back_populates="manager",
primaryjoin = "member_orgs.c.manager_id == User.id",
lazy="dynamic")
class Organization(SurrogatePK, Model):
"""An organization that Users may belong to."""
__tablename__ = 'organizations'
name = Column(db.Unicode(128), nullable=False)
members = relationship("MemberOrgsAssoc", back_populates="organization")
So sind alle oben SQLAlchemy Modellklassen und Beziehungen scheinen nun wie vorgesehen zu arbeiten.
Im Folgenden sind die drei Fabrik-Jungen-Klassen, die ich versuche, Arbeit zu machen.
MemberOrgs Verein-Objekt Fabrik:
class MemberOrgsAssocFactory(BaseFactory):
"""Association-object table Factory"""
class Meta:
"""Factory config"""
model = MemberOrgsAssoc
member_id = factory.SubFactory('tests.factories.UserFactory')
org_id = factory.SubFactory('tests.factories.OrganizationFactory')
manager_id = factory.SubFactory('tests.factories.UserFactory')
org_title = Sequence(lambda n: 'CEO{0}'.format(n))
organization = factory.SubFactory('tests.factories.OrganizationFactory')
member = factory.SubFactory('tests.factories.UserFactory')
manager = factory.SubFactory('tests.factories.UserFactory')
class UserFactory(BaseFactory):
"""User factory."""
class Meta:
"""Factory configuration."""
model = User
username = Sequence(lambda n: 'user{0}'.format(n))
organizations = factory.List(
[factory.SubFactory('tests.factories.MemberOrgsAssocFactory')])
subordinates = factory.List(
[factory.SubFactory('tests.factories.MemberOrgsAssocFactory')])
class OrganizationFactory(BaseFactory):
"""Company factory"""
class Meta:
"""Factory config"""
model = Organization
id = Sequence(lambda n: '{0}'.format(n))
name = Sequence(lambda n: 'company{0}'.format(n))
members = factory.List(
[factory.SubFactory('tests.factories.MemberOrgsAssocFactory')])
Schließlich müssen einen Benutzer für die Tests machen und so ist eine pytest Befestigung eines Benutzers zu machen. Dies ist, wo die Tests fehlschlagen aufgrund `RecursionError: maximale Rekursionstiefe überschritten“
@pytest.fixture(scope='function')
def user(db):
"""An user for the unit tests.
setup reference: https://github.com/FactoryBoy/factory_boy/issues/101
# how to handle self referential foreign key relation in factory boy
# https://github.com/FactoryBoy/factory_boy/issues/173
"""
user = UserFactory(
organizations__0=None,
subordinates__0=None,
)
a = MemberOrgsAssocFactory(
is_org_admin=True,
is_default_org=True,
is_active=True,
)
a.organization=OrganizationFactory()
user.organizations.append(a)
db.session.commit()
return user
Fehlermeldung:.
E RecursionError: maximum recursion depth exceeded
!!! Recursion detected (same locals & position)