使用Factory Boy通过Flask和SQLAlchemy定义三个相互关联的模型

时间:2019-05-02 14:00:45

标签: sqlalchemy factory-boy

我试图在Flask / SQLAlchemy站点中为三种具有复杂关系的模型创建FactoryBoy工厂。这些模型是:

from sqlalchemy.orm import backref
from ..shared import db


class User(db.Model):
    __tablename__ = "users"

    id = db.Column(db.Integer, primary_key=True)


class OAuth(db.Model):
    __tablename__ = "flask_dance_oauth"

    user_id = db.Column(db.Integer, db.ForeignKey(User.id), nullable=False)
    provider_user_id = db.Column(db.String(40), nullable=False)

    user = db.relationship(
        User,
        lazy="Joined",
        uselist=False,
        backref=backref("oauth", uselist=True, lazy="select"),
    )


class TwitterUserData(db.Model):
    "Stores data about the User's twitter account."
    __tablename__ = "twitter_user_data"

    id = db.Column(db.Integer, primary_key=True)
    id_str = db.Column(db.String(191), nullable=False, unique=True)

    user = db.relationship(
        "User",
        secondary="flask_dance_oauth",
        primaryjoin="and_("
            "OAuth.provider_user_id == TwitterUserData.id_str, "
            "OAuth.provider == 'twitter'"
        ")",
        secondaryjoin="User.id == OAuth.user_id",
        uselist=False,
        lazy="select",
        viewonly=True,
        backref=backref("twitter_data", uselist=False, lazy="select"),
    )

总结关系:

  • User.oauthOAuth对象
  • User.id映射到OAuth.user_id
  • User.twitter_dataTwitterUserData对象
  • TwitterUserData.userUser对象
  • TwitterUserData.id_str映射到OAuth.provider_user_id

我的工厂目前位于:

import factory


class OAuthFactory(factory.alchemy.SQLAlchemyModelFactory):
    class Meta:
        model = OAuth
        sqlalchemy_session = db.session
        sqlalchemy_session_persistence = "commit"


class TwitterUserDataFactory(factory.alchemy.SQLAlchemyModelFactory):
    class Meta:
        model = TwitterUserData
        sqlalchemy_session = db.session
        sqlalchemy_session_persistence = "commit"

    id_str = factory.Sequence(lambda n: (n * 1000000000000000))


class UserFactory(factory.alchemy.SQLAlchemyModelFactory):
    class Meta:
        model = User
        sqlalchemy_session = db.session
        sqlalchemy_session_persistence = "commit"

    twitter_data = factory.SubFactory(TwitterUserDataFactory)

    oauth = factory.SubFactory(
        OAuthFactory,
        user_id=factory.SelfAttribute("..id"),
        provider_user_id=factory.SelfAttribute("..twitter_data.id_str"),
    )

使用此设置,oauth.user_id无法设置,因为“参数'id'未知。”

相反,我尝试以此定义oauth,希望用户在post_generation中有一个id

    @factory.post_generation
    def oauth(obj, create, extracted, **kwargs):
        if not create:
            return
        oauth = oauth_factory(
            user_id=obj.id,
            provider_user_id=obj.twitter_data.id_str
        )
        return oauth 

但是这里obj.twitter_data'NoneType' object,这让我感到困惑。

我不确定还能尝试什么。

0 个答案:

没有答案