Closed razzius closed 10 years ago
I little bit dont understand what the reason for redefine __init__
method of SQLAlchemy models. But as one of solution you can easy create own mixer:
from mixer.backend.sqlalchemy import Mixer
class MyOwnMixer(Mixer):
def populate_target(self, values):
target = self.__scheme(**values)
return target
mixer = MyOwnMixer()
Maybe I will add this behavior as param to sqlalchemy mixer.
I do agree that using the default __init__
makes more sense — models with more than a couple fields are best constructed using named arguments rather than enforcing an arbitrary order.
Perhaps the Flask examples could be updated recommending this approach, if others feel the same way.
Updated README and docs.
Hi, Is this fix still working. I've tried creating my own mixer but it does not work. I tried to put a logger inside the populate_target
and its not triggering the log. I'm not sure with this but i think its not overriding the populate_target
. I'm not even sure if i'm doing it right. Can someone help me with this.
Here's the error
Traceback (most recent call last): File "/usr/local/lib/python3.5/dist-packages/mixer/main.py", line 568, in blend return type_mixer.blend(**values) File "/usr/local/lib/python3.5/dist-packages/mixer/main.py", line 134, in blend target = self.populate_target(values) File "/usr/local/lib/python3.5/dist-packages/mixer/backend/sqlalchemy.py", line 254, in populate_target target = self.__scheme() TypeError: Mixer (<class 'app.users.models.User'>): __init__() missing 3 required positional arguments: 'email', 'first_name', and 'last_name'
I ran into the same issue as @anthon-alindada - it looks like the code changed since the example in the README was created. This worked for me:
class CustomTypeMixer(TypeMixer):
def __init__(self, cls, mixer=None, factory=None, fake=True):
super().__init__(cls, mixer=mixer, factory=factory, fake=fake)
self.__scheme = cls # not sure why above line isn't setting this... is this the keyword 'cls' or just a variable named 'cls'?
def populate_target(self, values):
""" Populate a target by values. """
target = self.__scheme(**dict(values))
return target
class CustomMixer(Mixer):
type_mixer_cls = CustomTypeMixer
mixer = CustomMixer(session=session, commit=True)
organization = mixer.blend(Organization, internal_name='foo', name='Foo')
Consider the todo example from Flask-SQLAlchemy:
If we try to use mixer with it:
mixer
attempts to__init__
without any arguments, which throws an error. Would supporting a model defined this way be feasible/desirable?One way to get around this is to make all fields have defaults in the
__init__
:At the very least, putting a note in the docs that models with required
__init__
parameters are unsupported might save others some confusion.