-
Notifications
You must be signed in to change notification settings - Fork 394
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pass sequence to SubFactory #957
Comments
Could you show how you call the I can't reproduce this issue with simple factories 🤔 |
I just call it like that: from sqlalchemy import Column
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.mysql import SMALLINT, DECIMAL, INTEGER
class Position(Base):
id = Column(INTEGER(11), primary_key=True)
position_number = Column(SMALLINT(6))
position_account = relationship(
"PositionAccount",
primaryjoin="foreign(Position.position_number) == PositionAccount.position_number",
)
class PositionAccount(Base):
id = Column(INTEGER(11), primary_key=True)
payment_amount = Column(DECIMAL(10, 2), nullable=False) |
This should work. class PositionFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta:
model = models.Position
sqlalchemy_session_persistence = "commit"
sqlalchemy_session = models.session
position_number = factory.Sequence(lambda n: n)
position_account = factory.SubFactory(
PositionAccountFactory,
position_number=factory.Sequence(lambda n: n)
) @rbarrois can expand on this more/ or just correct me. But I think since your relationship between ^ Take this with a grain of salt Changes I made, and tests: class PositionAccount(Base):
id = Column(INTEGER(11), primary_key=True)
payment_amount = Column(DECIMAL(10, 2), nullable=False)
+ position_number = Column(SMALLINT(6)) # this was missing from your example, but you're referencing it (Everything else from your example code) class TestCase(TransactionTestCase):
def test_sequence(self):
position = PositionFactory()
self.assertEqual(position.position_number, 0)
self.assertEqual(position.position_account.position_number, 0)
self.assertEqual(position.position_account.payment_amount, 150)
position = PositionFactory()
self.assertEqual(position.position_number, 1)
self.assertEqual(position.position_account.position_number, 1)
self.assertEqual(position.position_account.payment_amount, 150) |
@kingbuzzman your example will only work as long as one never calls the When I write the code without SQLAlchemy, I see no issue: from dataclasses import dataclass
from decimal import Decimal
import factory
@dataclass
class PositionAccount:
position_number: int = None
payment_amount: Decimal = Decimal()
@dataclass
class Position:
position_number: int
position_account: PositionAccount
class PositionAccountFactory(factory.Factory):
position_number = None
payment_amount = Decimal("150.0")
class Meta:
model = PositionAccount
class PositionFactory(factory.Factory):
position_number = factory.Sequence(lambda n: n)
position_account = factory.SubFactory(
PositionAccountFactory,
position_number=factory.SelfAttribute("..position_number"),
)
class Meta:
model = Position With that, if I perform the following: p1, p2 = PositionFactory.create_batch(2)
pa3 = PositionAccountFactory() # Shift the sequence on the position account
p4 = PositionFactory(position_number=24)
p5 = PositionFactory()
assert p1.position_number == 0
assert p2.position_number == 1
assert pa3.position_number is None
assert p4.position_number == 24
assert p5.position_number == 3 # One step of the sequence was consumed by p4
for p in [p1, p2, p4, p5]:
assert p.position_number == p.position_account.position_number |
Ah I see what you mean, each Factory has its own sequence and I'm incrementing them in parallel, the second they fall behind for whatever reason, this whole thing falls apart -- right? That's what you're illustrating correct? How do you make it more robust? How can you use the sequence of the parent always? |
Mhm, is a mimimal reproductible case available? This does work with no problems
is there a chance the issue is in those sqla models @mademovic ? Did you ever try the |
Description
When copying a sequence to a SubFactory, the value of the field on the child factory is always 0.
To Reproduce
Model / Factory code
The issue
The sequence counter is ignored and the PositionAccount.position_number is always 0.
The text was updated successfully, but these errors were encountered: