Giter Site home page Giter Site logo

klen / mixer Goto Github PK

View Code? Open in Web Editor NEW
928.0 928.0 96.0 1.05 MB

Mixer -- Is a fixtures replacement. Supported Django, Flask, SqlAlchemy and custom python objects.

License: Other

Makefile 1.36% Python 98.64%
django flask sqlalchemy testing testing-tools

mixer's Introduction

https://raw.github.com/klen/mixer/develop/docs/_static/logo.png

The Mixer is a helper to generate instances of Django or SQLAlchemy models. It's useful for testing and fixture replacement. Fast and convenient test-data generation.

Mixer supports:

Tests Status Version Downloads License

Docs are available at https://mixer.readthedocs.org/. Pull requests with documentation enhancements and/or fixes are awesome and most welcome.

Описание на русском языке: http://klen.github.io/mixer.html

Important

From version 6.2 the Mixer library doesn't support Python 2. The latest version with python<3 support is mixer 6.1.3

  • Python 3.7+
  • Django (3.0, 3.1) for Django ORM support;
  • Flask-SQLALchemy for SQLAlchemy ORM support and integration as Flask application;
  • Faker >= 0.7.3
  • Mongoengine for Mongoengine ODM support;
  • SQLAlchemy for SQLAlchemy ORM support;
  • Peewee ORM support;

Mixer should be installed using pip:

pip install mixer
By default Mixer tries to generate fake (human-friendly) data.
If you want to randomize the generated values initialize the Mixer
by manual: Mixer(fake=False)
By default Mixer saves the generated objects in a database. If you want to disable
this, initialize the Mixer by manual like Mixer(commit=False)

Quick example:

from mixer.backend.django import mixer
from customapp.models import User, UserMessage

# Generate a random user
user = mixer.blend(User)

# Generate an UserMessage
message = mixer.blend(UserMessage, user=user)

# Generate an UserMessage and an User. Set username for generated user to 'testname'.
message = mixer.blend(UserMessage, user__username='testname')

# Generate SomeModel from SomeApp and select FK or M2M values from db
some = mixer.blend('someapp.somemodel', somerelation=mixer.SELECT)

# Generate SomeModel from SomeApp and force a value of money field from default to random
some = mixer.blend('someapp.somemodel', money=mixer.RANDOM)

# Generate SomeModel from SomeApp and skip the generation of money field
some = mixer.blend('someapp.somemodel', money=mixer.SKIP)

# Generate 5 SomeModel's instances and take company field's values from custom generator
some_models = mixer.cycle(5).blend('somemodel', company=(name for name in company_names))

Quick example:

from mixer.backend.flask import mixer
from models import User, UserMessage

mixer.init_app(self.app)

# Generate a random user
user = mixer.blend(User)

# Generate an userMessage
message = mixer.blend(UserMessage, user=user)

# Generate an UserMessage and an User. Set username for generated user to 'testname'.
message = mixer.blend(UserMessage, user__username='testname')

# Generate SomeModel and select FK or M2M values from db
some = mixer.blend('project.models.SomeModel', somerelation=mixer.SELECT)

# Generate SomeModel from SomeApp and force a value of money field from default to random
some = mixer.blend('project.models.SomeModel', money=mixer.RANDOM)

# Generate SomeModel from SomeApp and skip the generation of money field
some = mixer.blend('project.models.SomeModel', money=mixer.SKIP)

# Generate 5 SomeModel's instances and take company field's values from custom generator
some_models = mixer.cycle(5).blend('project.models.SomeModel', company=(company for company in companies))

For support this scheme, just create your own mixer class, like this:

from mixer.backend.sqlalchemy import Mixer

class MyOwnMixer(Mixer):

    def populate_target(self, values):
        target = self.__scheme(**values)
        return target

mixer = MyOwnMixer()

Example of initialization:

from mixer.backend.sqlalchemy import Mixer

ENGINE = create_engine('sqlite:///:memory:')
BASE = declarative_base()
SESSION = sessionmaker(bind=ENGINE)

mixer = Mixer(session=SESSION(), commit=True)
role = mixer.blend('package.models.Role')

Also, see Flask, Flask-SQLAlchemy.

Example usage:

from mixer.backend.mongoengine import mixer

class User(Document):
    created_at = DateTimeField(default=datetime.datetime.now)
    email = EmailField(required=True)
    first_name = StringField(max_length=50)
    last_name = StringField(max_length=50)
    username = StringField(max_length=50)

class Post(Document):
    title = StringField(max_length=120, required=True)
    author = ReferenceField(User)
    tags = ListField(StringField(max_length=30))

post = mixer.blend(Post, author__username='foo')

Example usage:

from mixer.backend.marshmallow import mixer
import marshmallow as ma

class User(ma.Schema):
    created_at = ma.fields.DateTime(required=True)
    email = ma.fields.Email(required=True)
    first_name = ma.fields.String(required=True)
    last_name = ma.fields.String(required=True)
    username = ma.fields.String(required=True)

class Post(ma.Schema):
    title = ma.fields.String(required=True)
    author = ma.fields.Nested(User, required=True)

post = mixer.blend(Post, author__username='foo')

Quick example:

from mixer.main import mixer

class Test:
    one = int
    two = int
    name = str

class Scheme:
    name = str
    money = int
    male = bool
    prop = Test

scheme = mixer.blend(Scheme, prop__one=1)

By default 'django', 'flask', 'mongoengine' backends tries to save objects in database. For preventing this behavior init mixer manually:

from mixer.backend.django import Mixer

mixer = Mixer(commit=False)

Or you can temporary switch context use the mixer as context manager:

from mixer.backend.django import mixer

# Will be save to db
user1 = mixer.blend('auth.user')

# Will not be save to db
with mixer.ctx(commit=False):
    user2 = mixer.blend('auth.user')

The mixer allows you to define generators for fields by manually. Quick example:

from mixer.main import mixer

class Test:
    id = int
    name = str

mixer.register(Test,
    name=lambda: 'John',
    id=lambda: str(mixer.faker.small_positive_integer())
)

test = mixer.blend(Test)
test.name == 'John'
isinstance(test.id, str)

# You could pinned just a value to field
mixer.register(Test, name='Just John')
test = mixer.blend(Test)
test.name == 'Just John'

Also, you can make your own factory for field types:

from mixer.backend.django import Mixer, GenFactory

def get_func(*args, **kwargs):
    return "Always same"

class MyFactory(GenFactory):
    generators = {
        models.CharField: get_func
    }

mixer = Mixer(factory=MyFactory)

You can add middleware layers to process generation:

from mixer.backend.django import mixer

# Register middleware to model
@mixer.middleware('auth.user')
def encrypt_password(user):
    user.set_password('test')
    return user

You can add several middlewares. Each middleware should get one argument (generated value) and return them.

It's also possible to unregister a middleware:

mixer.unregister_middleware(encrypt_password)

By default mixer uses 'en' locale. You could switch mixer default locale by creating your own mixer:

from mixer.backend.django import Mixer

mixer = Mixer(locale='it')
mixer.faker.name()          ## u'Acchisio Conte'

At any time you could switch mixer current locale:

mixer.faker.locale = 'cz'
mixer.faker.name()          ## u'Miloslava Urbanov\xe1 CSc.'

mixer.faker.locale = 'en'
mixer.faker.name()          ## u'John Black'

# Use the mixer context manager
mixer.faker.phone()         ## u'1-438-238-1116'
with mixer.ctx(locale='fr'):
    mixer.faker.phone()     ## u'08 64 92 11 79'

mixer.faker.phone()         ## u'1-438-238-1116'

If you have any suggestions, bug reports or annoyances please report them to the issue tracker at https://github.com/klen/mixer/issues

Development of mixer happens at Github: https://github.com/klen/mixer

Licensed under a BSD license.

mixer's People

Contributors

anis-campos avatar camrock1 avatar cheungpat avatar dmitriymoseev avatar eelkeh avatar egabancho avatar emlync avatar f30 avatar illia-v avatar imbaczek avatar ivanistheone avatar jairhenrique avatar jayvdb avatar jberkel avatar jbrissier avatar jnns avatar jomasti avatar klen avatar lucasrcezimbra avatar marazmiki avatar marigold avatar matheusho avatar mcbloch avatar mtilda avatar myusuf3 avatar odigity avatar orsinium avatar pavlov99 avatar suriya avatar zzzsochi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mixer's Issues

Naive/Aware timezones support for django.

@klen , does mixer support timezone naive and timezone aware datetime/date generation for django now? Currently I have warnings, such as:

03.12 12:24:21 py.warnings  WARNING [removed_path]/.env/local/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py:53: RuntimeWarning: SQLite received a naive datetime (2014-12-03 12:24:21.796532) while time zone support is active.
  RuntimeWarning)

mixer version: 4.9.5
If aware timezones are not supported, I could implement it.

Prevent distasteful sample content

I'm using mixer to generate sample data for a software demo in a relatively conservative industry. As such, I don't want to be showing a demo of my software and have things like [email protected] (that's a real world example) show up as an email address - it makes us look immature when we're presenting our software to enterprise clients.

I realize we're not going to eliminate the possibility of suggestive content getting populated from time to time, but I see no reason to invite it.

Would you be open to removing some of the more explicit sample content, or providing a way to disable it? I'd be happy to do some of the work and submit a pull request, just wanted to ask first.

object has no attribute _sa_instance_state

I am trying to upgrade a project from mixer 0.6.3 to the latest version 5.0.6 but I am having some problems with fixtures using the cycle shortcut. This is a SQAlchemy project.

The following code fails:

john = mixer.blend(Actor, name='John')
cesar = mixer.blend(Actor, name='Cesar')

mixer.cycle(3).blend(Movie, actor=(x for x in (cesar, cesar, john)))

Here is the traceback:

.venv/local/lib/python2.7/site-packages/mixer/main.py:591: in blend
    return type_mixer.blend(**values)
.venv/local/lib/python2.7/site-packages/mixer/main.py:119: in blend
    deferred_values = list(self.fill_fields(target, defaults))
.venv/local/lib/python2.7/site-packages/mixer/main.py:149: in fill_fields
    deferred = self.set_value(target, fname, value)
.venv/local/lib/python2.7/site-packages/mixer/backend/sqlalchemy.py:133: in set_value
    field_value)[1][0])
.venv/local/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py:2288: in identity_key_from_instance
    self.primary_key_from_instance(instance))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def emit_backref_from_scalar_set_event(state, child, oldchild, initiator):
        if oldchild is child:
            return child
        if oldchild is not None and \
                oldchild is not PASSIVE_NO_RESULT and \
                oldchild is not NEVER_SET:
            # With lazy=None, there's no guarantee that the full collection is
            # present when updating via a backref.
            old_state, old_dict = instance_state(oldchild),\
                instance_dict(oldchild)
            impl = old_state.manager[key].impl

            if initiator.impl is not impl or \
                    initiator.op not in (OP_REPLACE, OP_REMOVE):
                impl.pop(old_state,
                         old_dict,
                         state.obj(),
                         parent_impl._append_token,
                         passive=PASSIVE_NO_FETCH)

        if child is not None:
>           child_state, child_dict = instance_state(child),\
                instance_dict(child)
E           AttributeError: Mixer (<class 'test.Movie'>): 'generator' object has no attribute '_sa_instance_state'

Creating the fixture without the cycle shortcut works file, so I can workaround this problem by using a for loop.

I tested this with various Mixer version and it seems that the problem was introduced on version 3.0.0. It works file with version 2.3.0.

Way to alter "magic" fieldname-based logic

I have a model User with a field named name. But that field represent user login, so it should not contain whitespaces and dots. So values like Dr. John Smith do not fit.
Which is the "good" way to achieve this?
From documentation I found a Mixer.register method. But if I create a function, how could I use Mixer's internals to generate a "good" fake value?

Django tests failing with PostgreSQL database backend

Can someone confirm that the mixer test suite does not pass all of the Django backend tests?

I'm currently having trouble getting all my project's tests to pass since switching the test database backend from SQLite to Postgres and discovered that mixer seems to have issues with certain field type validations (i.e. max-length restrictions, smallint out of range etc...).

Results (30.89s):
48 passed
13 failed
- tests/test_django.py:31 test_fields
- tests/test_django.py:76 test_custom
- tests/test_django.py:116 test_select
- tests/test_django.py:130 test_relation
- tests/test_django.py:191 test_random
- tests/test_django.py:200 test_mix
- tests/test_django.py:223 test_contrib
- tests/test_django.py:255 test_skip
- tests/test_django.py:261 test_generic
- tests/test_django.py:274 test_deffered
- tests/test_django.py:291 test_guard
- tests/test_django.py:298 test_reload
- tests/test_django.py:310 test_small_positive_integer_field_not_too_large
2 skipped

Tried running the tests with current mixer master branch and the following package versions:

Django==1.10.5
psycopg2==2.6.2
pytest==3.0.5
--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/40649900-django-tests-failing-with-postgresql-database-backend?utm_campaign=plugin&utm_content=tracker%2F327725&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F327725&utm_medium=issues&utm_source=github).

Are mangled names necessary?

Double underscore variables like these:

self.__fields = _.OrderedDict(self.__load_fields())

Are being used extensively in the TypeMixer class.

According to the docs, the official use case for those mangled names is "to avoid name clashes of names with names defined by subclasses".

However, this is not how those are used in the mixer library. Methods like __load_fields are overridden in almost every subclass. Since the method names gets mangled, all subclasses are forced to call themselves TypeMixer as well in order to get around the mangling.

I just spent a few hours figuring this surprising behavior out, and I don't see any real benefits to forcing subclasses to call themselves "TypeMixer" for them to work. Am I missing something? If there is a real benefit here, it would be great if there is some sort of highly visible documentation for developers who wish to subclass TypeMixers.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/40628090-are-mangled-names-necessary?utm_campaign=plugin&utm_content=tracker%2F327725&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F327725&utm_medium=issues&utm_source=github).

user defined activation function

Hello,
I would like to build RBF neural network using mxnet, but the gaussian activation function is not available (there is only sigmoid, relu or tanh)
could you please tell me how and where can I add it ?

Thanks!

RuntimeError: Mixer (app.Model): Cannot generate a unique value for user

I'm getting this error in a large Django codebase with hundreds of tests. I believe this happens because all instances that mixer creates are somehow cached and after a while it runs out of dictionary words to create new instances because it compares against the cache and not against the DB (which is obviously empty after each test).

I kind of pinned it down to this loop in main.py and the fact that TypeMixer derives from TypeMixerMeta which has "Cache typemixers by scheme." as a docstring makes me think that these instances might act like singletons and are not properly destroyed between tests, so that self.__gen_values will probably just fill up more and more until the dictionary cannot produce unique items any more.

Is there any workaround for this?

In my case I have a UserProfile model which has a OneToOneKey to the auth.User model and I'm usually creating profiles with mixer.blend('user_profile.UserProfile') which then automatically also tries to mix the user for the profile.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/32818307-runtimeerror-mixer-app-model-cannot-generate-a-unique-value-for-user?utm_campaign=plugin&utm_content=tracker%2F327725&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F327725&utm_medium=issues&utm_source=github).

Make mixer date generator timezone aware

Hi there!

We encountered a little problem with the date generator of mixer in django.

Our django is set up to be timezone aware and so are the date attributes in the db - for example the register_date of the model Customer. So when we are blending a customer by calling:

mixer.blend(Customer)

we get a

RuntimeWarning: DateTimeField Customer.register_date received a naive datetime (1973-04-22 14:31:06) while time zone support is active. RuntimeWarning)

Is there a possibility to add time zone awareness to the date generator? At the moment we work around this problem by the following code:

mixer.blend(Customer, register_date=timezone.now())

For one model thats ok. But as the code base is growing this problem could get bigger...

Mixer working with postgresql.INET fields?

I have a model to save the Ip Addres of my users, saving it like this...

addr_ip = DB.column(postgresql.INET, nullable=False

and when trying to generate a mixed object it raises a uncaught exception in factory.py,

NoneType has no attribute ___bases__

if not func and fcls.__bases__:
func = cls.generators.get(fcls.__bases__[0])

This is called in main.py line 314

fabric = self.__factory.gen_maker(scheme, field_name, fake)

And the issue is that the scheme parameter is empty. When I searched in mix_types, I saw an IP4string, IP6string and IPstring, these don't get along with INET type? It currently appears to not see the Column schema correctly.

Compatibility with faker 0.5.2

Starting from faker 0.5.2, faker don't have DEFAULT_PROVIDER anymore, replaced by PROVIDER

If you agree with that I can write the fix (with compatibility for old version)

Value too long for type character varying(24)

My test cases getting fail since I switch the test database backend from SQLite to Postgres. I am creating a model instance using mixer and it is throwing the following error.
"Value too long for type character varying(24)"
There is a field where it is showing the error:
code = models.CharField(_('Code'), max_length=24, null=False, blank=False,
db_column='code', default=uuid.uuid4, unique=True)
I am not getting whats wrong with it.
Please help.

Skip Django related models generation when primary key is provided

It would be nice to skip generation of related Django model when related key is provided. Example:

class Author(models.Model):
    ... 

class Book(models.Model):
      author = models.ForeignKey(Author)
       ...
# don't generate extra author instance
mixer.blend(Book, author_id=3)

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/6290149-skip-django-related-models-generation-when-primary-key-is-provided?utm_campaign=plugin&utm_content=tracker%2F327725&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F327725&utm_medium=issues&utm_source=github).

Update faker version

mixer 5.5.6 specifies faker==0.7.3.

The latest version of faker==0.7.10 and includes support for Python 3.6.

Broken pypi metadata

The mixer metadata is broken in https://pypi.python.org/pypi/mixer.

One bad side effect of this is the check of python3 compatibility that canIusepython3 does. It uses the classifiers to search for python 3. It's a false negative caused by the broken metadata.

Best regards!

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/25691765-broken-pypi-metadata?utm_campaign=plugin&utm_content=tracker%2F327725&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F327725&utm_medium=issues&utm_source=github).

Exceptions thrown from related model being represented as coming from the relationship property itself.

I came across an error when using Mixer, but the stack trace sent me in the wrong direction at first. The trace indicated there was a problem processing a SQLAlchemy relationship definition. I eventually discovered that the error wasn't on the relationship itself, but one of the columns in the related table was creating issues. The misdirection in this stack trace made it very difficult to debug.

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/mixer/main.py", line 576, in blend
    return type_mixer.blend(**values)
  File "/usr/local/lib/python2.7/site-packages/mixer/main.py", line 125, in blend
    for name, value in defaults.items()
  File "/usr/local/lib/python2.7/site-packages/mixer/main.py", line 125, in <genexpr>
    for name, value in defaults.items()
  File "/usr/local/lib/python2.7/site-packages/mixer/mix_types.py", line 220, in gen_value
    return type_mixer.gen_field(field)
  File "/usr/local/lib/python2.7/site-packages/mixer/main.py", line 202, in gen_field
    return self.gen_value(field.name, field, unique=unique)
  File "/usr/local/lib/python2.7/site-packages/mixer/main.py", line 255, in gen_value
    field_name, self.__scheme.__name__, exc))
ValueError: Mixer (myproject.models.Order): Generation for customer (Order) has been stopped. Exception: 'NoneType' object has no attribute '__bases__'

That last line should read something like this, with perhaps a reference that it was coming from myproject.models.Order:

ValueError: Mixer (myproject.models.Customer): Generation for time_created (Customer) has been stopped. Exception: 'NoneType' object has no attribute '__bases__'

See data before is inserted

Hi, is there any way to get all the data to be inserted in the database when I use commit=False?

When developing it's much easier for me to see if the objects I'm going to insert are correct. Thanks!

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

Many2Many field - Django - mixer.SELECT not working

I saw this in documentation and tried to implement the same. mixer.RANDOM is working fine with m2m field. I will write a failing test case for the same.

# Generate SomeModel from SomeApp and select FK or M2M values from db
some = mixer.blend('someapp.somemodel', somerelation=mixer.SELECT)

Error.....
ValueError: Mixer (projects.Project): "<Project: Mr. Kamron Kemmer>" needs to have a value for field "project" before this many-to-many relationship can be used.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/36508333-many2many-field-django-mixer-select-not-working?utm_campaign=plugin&utm_content=tracker%2F327725&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F327725&utm_medium=issues&utm_source=github).

Django object with string imports aren't committed

I use the standard setup off your app and we use your app in several projects, but never had this issue.

This works:

from .. import models
self.object = mixer.blend(models.ModelName)
self.assertTrue(models.ModelName.objects.all())

Somehow this doesn't work:

from .. import models
self.object = mixer.blend('app.ModelName')
self.assertTrue(models.ModelName.objects.all())

I wasn't able to find out, why they aren't added to the database. Any ideas?
Thanks in advance!

Handle Django multi-table inheritance

I try to blend instance of child model with commit=False. The model is inherited from auth.User model, using multi-table inheritance. I get following error:

Cannot generate a unique value for user_ptr

Disable gereration values

Hi,

In specific case i would like to completely disable generation of random/fake values. I tried to override some Mixer components without success.

Is it possible ?

Thanks,

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/32359479-disable-gereration-values?utm_campaign=plugin&utm_content=tracker%2F327725&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F327725&utm_medium=issues&utm_source=github).

How to use m2m with flask?

Here is what I've tried:

mixer.blend(User, roles=[Role.query.filter_by(name='admin').one()])
AttributeError: Mixer (<class 'xx.models.User'>): 'list' object has no attribute '_sa_instance_state'

mixer.blend(User, roles=mixer.SELECT(name='admin'))
TypeError: Mixer (<class 'xx.models.User'>): Incompatible collection type: Role is not list-like

mixer.blend(User, roles=mixer.MIX)
TypeError: Mixer (<class 'xx.models.User'>): issubclass() arg 1 must be a class

mixer.blend(User, roles=mixer.cycle(3).blend(Role))
AttributeError: Mixer (<class 'xx.models.User'>): 'list' object has no attribute '_sa_instance_state'

and so on...

What is the proper way to use mixer with m2m relationships?

Does Flask-SQLAlchemy actually work with Mixer?

The documentation is pretty clear, but I can't seem to get it working with a simple example, it doesn't populate the email or username fields in the below example. If you could point me in the right direction I'll try my best to clear up the confusion in the docs.

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from mixer.backend.flask import mixer

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'

db = SQLAlchemy(app)
mixer.init_app(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    email = db.Column(db.String(120), unique=True)

    def __repr__(self):
        return '<User %r>' % self.username

if __name__ == '__main__':
    with app.app_context():
        db.create_all()
        user = mixer.blend(User)
        print user.id, user.username

        #Result: 1 None

Create a way to define custom Types and Generators and error descriptively when Types are not recognized.

I defined a couple custom SQLAlchemy types with sqlalchemy.types.TypeDecorator, and immediately Mixer choked on them. I had to reverse-engineer the system and monkey-patch my custom types in order to get it working.

Here's a link to my Stack Overflow post about this, including the hacky solution I implemented, and here's the traceback I got:

mixer: ERROR: Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/mixer/main.py", line 576, in blend
    return type_mixer.blend(**values)
  File "/usr/local/lib/python2.7/site-packages/mixer/main.py", line 125, in blend
    for name, value in defaults.items()
  File "/usr/local/lib/python2.7/site-packages/mixer/main.py", line 125, in <genexpr>
    for name, value in defaults.items()
  File "/usr/local/lib/python2.7/site-packages/mixer/mix_types.py", line 220, in gen_value
    return type_mixer.gen_field(field)
  File "/usr/local/lib/python2.7/site-packages/mixer/main.py", line 202, in gen_field
    return self.gen_value(field.name, field, unique=unique)
  File "/usr/local/lib/python2.7/site-packages/mixer/main.py", line 245, in gen_value
    fab = self.get_fabric(field, field_name, fake=fake)
  File "/usr/local/lib/python2.7/site-packages/mixer/main.py", line 290, in get_fabric
    self.__fabrics[key] = self.make_fabric(field.scheme, field_name, fake)
  File "/usr/local/lib/python2.7/site-packages/mixer/backend/sqlalchemy.py", line 178, in make_fabric
    stype, field_name=field_name, fake=fake, kwargs=kwargs)
  File "/usr/local/lib/python2.7/site-packages/mixer/main.py", line 306, in make_fabric
    fab = self.__factory.get_fabric(scheme, field_name, fake)
  File "/usr/local/lib/python2.7/site-packages/mixer/factory.py", line 158, in get_fabric
    if not func and fcls.__bases__:
AttributeError: Mixer (myproject.models.MyModel): 'NoneType' object has no attribute '__bases__'

Anyway, thanks for making Mixer! It's a really powerful tool, and I love anything that makes testing easier.

Django 1.7 support?

Trying to run this with Django 1.7, it's obvious it's not compatible. I get errors like:

File "/Users/dan/cenv/lib/python2.7/site-packages/mixer/backend/django.py", line 140, in __update_cache
for app_models in models.loading.cache.app_models.values():

AttributeError: 'module' object has no attribute 'loading'

Is there a plan for this to support 1.7?

Data generation and UUIDType from SQLAlchemy Utils

Hello there,

Thank you for mixer, it is a very useful tool. I use it to test an API based on Flask Restful and Postgres. But I face an issue. When I want to use a UUIDType column in my database schema, it is not recognized and Mixer can't give a value to it (this type comes from SQLAlchemy utils).

I tried this solution:

from mixer.backend.sqlalchemy import GenFactory
GenFactory.generators[UUIDType] = my_generator

But it doesn't work. Do you have any idea about what to do to make it work?

Peewee backend doesn't commit by default

I found this surprising, and it seems like a bug, but the Peewee backend doesn't save by default. It seems like it should default to committing, like the Django backend does. Here's a simple test case:

from mixer.backend.peewee import mixer
from models import Foo
print(Foo.select().count())  # 0
mixer.blend(Foo)
print(Foo.select().count())  # Still 0, which was unexpected.

Doing this works just fine, but it's not documented anywhere that this is required:

with mixer.ctx(commit=True):
    foo = mixer.blend(Foo)

Support for Flask-SQLAlchemy models that have `__init__` arguments

Consider the todo example from Flask-SQLAlchemy:

from datetime import datetime
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from mixer.backend.sqlalchemy import mixer

app = Flask(__name__)
db = SQLAlchemy(app)

class Todo(db.Model):
    __tablename__ = 'todos'
    id = db.Column('todo_id', db.Integer, primary_key=True)
    title = db.Column(db.String(60))
    text = db.Column(db.String)
    pub_date = db.Column(db.DateTime)

    def __init__(self, title, text):
        self.title = title
        self.text = text
        self.pub_date = datetime.utcnow()

If we try to use mixer with it:

mixer.blend(Todo)

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-8a1d24676132> in <module>()
     19         self.pub_date = datetime.utcnow()
     20
---> 21 mixer.blend(Todo)

/Users/razzi/local/venvs/thornm/lib/python2.7/site-packages/mixer/main.pyc in blend(self, scheme, **values)
    596         type_mixer = self.get_typemixer(scheme)
    597         try:
--> 598             return type_mixer.blend(**values)
    599         except Exception:
    600             if self.params.get('silence'):

/Users/razzi/local/venvs/thornm/lib/python2.7/site-packages/mixer/main.pyc in blend(self, **values)
    145                 values.append((name, value))
    146
--> 147         target = self.populate_target(values)
    148
    149         # Run registered middlewares

/Users/razzi/local/venvs/thornm/lib/python2.7/site-packages/mixer/main.pyc in populate_target(self, values)
    168     def populate_target(self, values):
    169         """ Populate target with values. """
--> 170         target = self.__scheme()
    171         for name, value in values:
    172             setattr(target, name, value)

TypeError: __init__() takes exactly 3 arguments (1 given)

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__:

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(50), unique=True)
    email = Column(String(120), unique=True)

    def __init__(self, name=None, email=None):
        self.name = name
        self.email = email

At the very least, putting a note in the docs that models with required __init__ parameters are unsupported might save others some confusion.

Does mixer fill data into Django image fields?

Before I dive deep into the code I thought I might as well quickly ask:

I realized that my tests have become incredibly slow and I have pinned down the problem to models that have ImageFields. When I use mixer.blend('app.Model', image=None), the test runs in 0.005ms but when I use mixer.blend('app.Model)`, then the test runs in 1,123ms (!!!)

Is there a way to globally disable that mixer does anything with Django ImageFields?

Map AutoField as None

At the moment Django models.AutoField is mapped as t.PositiveInteger. There is no need to generate values for models.AutoField because it relies on database feature like auto increment and sequences.

Now I have to do following hack in my GenFactory:

types = {
        models.AutoField: type(None),
        models.PositiveIntegerField: t.PositiveInteger,
        (models.AutoField, models.PositiveIntegerField): type(None),
    }

UPDATE: actually this hack doesn't work for me

In my opinion it's better to use database features for primary key generation.

Generate an unsaved instance

Thanks for building this library! Are there any plans to add functionality to create model instances that have not yet been saved to the database?

support for object generation from marshmallow schema

Hi,

is there any interest in adding support for generating objects based on marshmallow schema?

https://github.com/marshmallow-code/marshmallow

I took a cursory look - very roughly, it seems a map of schema field types to generator types is needed. what else would be involved?

or perhaps it is practical to use the ORM backend and simply constrain the fields to those used in the marschmallow schema...


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

How easy is it to switch from milkman to mixer?

I have some code using milkman. How hard would it be to switch from milkman to mixer?

Already, I see that my milkman.deliver calls will have to use a non-saving Mixer(commit=False) instance. What other differences should I be aware of?

I'm just curious: Is any of the mixer code taken directly from the milkman project?

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

Mixer generate a number higher then MaxValueValidator

hi @klen I am having an error with my model when I use as a constraint Min/MaxValueValidator.

from django.core.validators import MinValueValidator, MaxValueValidator

class Course(models.Model):
    number_of_minutes = models.PositiveIntegerField(
            validators=[
            MinValueValidator(12),
            MaxValueValidator(60)
            ]
        )

in the shell

course = mixer.blend(Course)
course.number_of_minutes 
 =>  5645

So I want to know how to have the MaxValueValidator constraint

mixer for peewee AttributeError: 'ModelOptions' object has no attribute 'get_sorted_fields'

my peewee model is like this:

class Vendor(Model):
    erp_id = IntegerField(primary_key=True)
    name = CharField(max_length=128)
    app_id = CharField(max_length=32)
    secret = CharField(max_length=64)

    class Meta:
        database = db

And mixer the model in my unit test

self.vendor = mixer.blend(Vendor)

Then I got the error:

    for name, field in self.__scheme._meta.get_sorted_fields():
AttributeError: 'ModelOptions' object has no attribute 'get_sorted_fields'

I do not know how to solve it.

Add support/backend for Serializers (DjangoRestFramework, MarshMallow)?

Hello Folks,

I was thinking about the possibility of the support for some general serializers like MarshMallow and DjangoRestFramework.

It Would Be something like:

from mixer.backends.drfserializer import mixer
from app.serializers import ProjectSerializer

project = mixer.blend(ProjectSerializer)

The biggest difference here is that we don't need to write the results to a database, just verify if the data generated is valid (call a is_valid method most the time) .

What do you think? Is this an acceptable request?

PS: I'm willing to fork and help with django rest frameworks if this request is marked as an acceptable enhancement.

Flask default mixer, commit is set to "False"

In the documentation you describe that the commit is enabled by default:

"By default Mixer saves generated objects in database. If you want disable
this, initialize the Mixer by manual like: Mixer(commit=False)"

But in the flask default mixer you set it to False.

I have no opinion on what the default should be, just wanted to report this.

Mixer for my flask app gives error when used with db.init_app() -- AttributeError: 'module' object has no attribute 'extensions'

Hi,

I am trying to use mixer with my flask app to create fake data. I have written below mixer module

# module: my-mixer.py
from flask import Flask
from mixer.backend.flask import mixer
from faker import Faker

from database import db
from models import Country
from recruitment import app

app = flask.Flask('myapp')
db.init_app(app)
db.app = app

fake = Faker()

mixer.init_app(app)

# Generate a random country
country = mixer.blend(Country)

# Generate a Country. Set country name.
country = mixer.blend(Country, country__name=fake.country())

The db is taken from

from flask.ext.sqlalchemy import SQLAlchemy
# no app object passed! Instead we use use db.init_app in the factory.
db = SQLAlchemy()

You can see that I am not directly binding app with db

db = SQLAlchemy(app)

Now when I run my-mixer.py, I get below error

Traceback (most recent call last):
File "faker-mixer.py", line 16, in <module>
mixer.init_app(app)
File "/home/hussain/workspace/test/venv/local/lib/python2.7/site-packages/mixer/backend/flask.py", line 45, in init_app
assert app.extensions and app.extensions[
AttributeError: 'module' object has no attribute 'extensions'

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

sqlalchemy_utils ChoiceType nullable failure

I defined a column as sqlalchemy_utils ChoiceType

class JzPlan(db.Model):
    CREATED = u'CREATED'
    ASSIGNED = u'ASSIGNED'
    CHECKED = u'CHECKED'
    PLAN_STATUS = [
    (CREATED, u'A'),
    (ASSIGNED, u'B'),
    (CHECKED, u'C'),
   ]
    id = db.Column(db.Integer(), primary_key=True)
    ddbh = db.Column(db.String(50), nullable=False)
    xqf = db.Column(db.String(50), nullable=False)
    xmpc = db.Column(db.String(50), nullable=False)
    jslx = db.Column(db.String(50), nullable=False)
    ds = db.Column(db.String(50), nullable=False)
    qx = db.Column(db.String(50), nullable=False)
    zm = db.Column(db.String(50), nullable=False)
    xxdz = db.Column(db.String(50), nullable=False)
    fgcj = db.Column(db.String(50), nullable=False)
    ysjfsj = db.Column(db.DateTime, nullable=False)
    qyjl_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    qyjl = db.relation(User, innerjoin=True, lazy="joined")
    status = db.Column(ChoiceType(PLAN_STATUS))
    enabled = db.Column(db.Boolean, default=True, nullable=False)

then I set the mixer as below, that's OK:

plan = mixer.blend(JzPlan)

but I set the status nullable attribute, the failure raised.

status = db.Column(ChoiceType(PLAN_STATUS), nullable=False)

The error message as below:

---------------------------- Captured stderr call -----------------------------
Traceback (most recent call last):
  File "D:\Develop\Python\env\towerprice\lib\site-packages\mixer\main.py", line 577, in blend
return type_mixer.blend(**values)
  File "D:\Develop\Python\env\towerprice\lib\site-packages\mixer\main.py", line125, in blend for name, value in defaults.items()
  File "D:\Develop\Python\env\towerprice\lib\site-packages\mixer\main.py", line125, in <genexpr>
for name, value in defaults.items()
File "D:\Develop\Python\env\towerprice\lib\site-packages\mixer\mix_types.py",line 220, in gen_value
return type_mixer.gen_field(field)
File "D:\Develop\Python\env\towerprice\lib\site-packages\mixer\main.py", line202, in gen_field
return self.gen_value(field.name, field, unique=unique)
File "D:\Develop\Python\env\towerprice\lib\site-packages\mixer\main.py", line245, in gen_value
fab = self.get_fabric(field, field_name, fake=fake)
File "D:\Develop\Python\env\towerprice\lib\site-packages\mixer\main.py", line291, in get_fabric
self.__fabrics[key] = self.make_fabric(field.scheme, field_name, fake)
File "D:\Develop\Python\env\towerprice\lib\site-packages\mixer\backend\sqlalchemy.py", line 181, in make_fabric
stype, field_name=field_name, fake=fake, kwargs=kwargs)
File "D:\Develop\Python\env\towerprice\lib\site-packages\mixer\main.py", line307, in make_fabric
fab = self.__factory.get_fabric(scheme, field_name, fake)
File "D:\Develop\Python\env\towerprice\lib\site-packages\mixer\factory.py", line 159, in get_fabric
if not func and fcls.__bases__:
AttributeError: Mixer (<class 'towerprice.models.JzPlan'>): 'NoneType' object has no attribute '__bases__'

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/27320839-sqlalchemy_utils-choicetype-nullable-failure?utm_campaign=plugin&utm_content=tracker%2F327725&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F327725&utm_medium=issues&utm_source=github).

Custom generators for type.

How can i use custom generator for some types. For example i wanna change min_datetime and max_datetime in get_datetime.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.