Я пытаюсь создать фабрики FactoryBoy для трех моделей со сложными отношениями на сайте Flask / SQLAlchemy. Модели:
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.oauth
является OAuth
объектом
User.id
отображается на OAuth.user_id
User.twitter_data
является TwitterUserData
объектом
TwitterUserData.user
является User
объектом
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
, что меня озадачивает.
Я не уверен, что еще попробовать.