Example #1
0
def test_cycle(session):
    from mixer.backend.sqlalchemy import Mixer

    mixer = Mixer(session=session, commit=True)
    profile1 = mixer.blend('tests.test_sqlalchemy.Profile', name='first')
    profile2 = mixer.blend('tests.test_sqlalchemy.Profile', name='second')
    users = mixer.cycle(2).blend(User, profile=(p for p in (profile1, profile2)))
    assert len(users) == 2
    assert users[0].profile.name == 'first'
    assert users[1].profile.name == 'second'
Example #2
0
def test_cycle(session):
    from mixer.backend.sqlalchemy import Mixer

    mixer = Mixer(session=session, commit=True)
    profile1 = mixer.blend('tests.test_sqlalchemy.Profile', name='first')
    profile2 = mixer.blend('tests.test_sqlalchemy.Profile', name='second')
    users = mixer.cycle(2).blend(User, profile=(p for p in (profile1, profile2)))
    assert len(users) == 2
    assert users[0].profile.name == 'first'
    assert users[1].profile.name == 'second'
Example #3
0
def test_select(session):
    from mixer.backend.sqlalchemy import Mixer

    mixer = Mixer(session=session, commit=True)

    users = session.query(User).all()
    role = mixer.blend(Role, user=mixer.SELECT)
    assert role.user in users

    user = users.pop()
    role = mixer.blend(Role, user=mixer.SELECT(User.id == user.id))
    assert user == role.user
Example #4
0
    def test_select(self):
        from mixer.backend.sqlalchemy import Mixer

        mixer = Mixer(session=self.session, commit=True)

        users = self.session.query(User).all()
        role = mixer.blend(Role, user=mixer.select)
        self.assertTrue(role.user in users)

        user = users.pop()
        role = mixer.blend(Role, user=mixer.select(User.id == user.id))
        self.assertEqual(user, role.user)
Example #5
0
def test_select(session):
    from mixer.backend.sqlalchemy import Mixer

    mixer = Mixer(session=session, commit=True)

    users = session.query(User).all()
    role = mixer.blend(Role, user=mixer.SELECT)
    assert role.user in users

    user = users.pop()
    role = mixer.blend(Role, user=mixer.SELECT(User.id == user.id))
    assert user == role.user
Example #6
0
    def test_select(self):
        from mixer.backend.sqlalchemy import Mixer

        mixer = Mixer(session=self.session, commit=True)

        users = self.session.query(User).all()
        role = mixer.blend(Role, user=mixer.select)
        self.assertTrue(role.user in users)

        user = users.pop()
        role = mixer.blend(Role, user=mixer.select(User.id == user.id))
        self.assertEqual(user, role.user)
Example #7
0
def test_mixer(session):
    from mixer.backend.sqlalchemy import Mixer

    mixer = Mixer(session=session, commit=True)
    p = mixer.blend('tests.test_sqlalchemy.ProfileNonIncremental', id=5)
    role = mixer.blend('tests.test_sqlalchemy.Role', user__profile_id_nonincremental=p)
    assert role and role.user

    role = mixer.blend(Role, user__name='test2')
    assert role.user.name == 'test2'

    profile = mixer.blend('tests.test_sqlalchemy.Profile')
    user = mixer.blend(User, profile__name='test')
    assert user.profile.name == 'test'

    user = mixer.blend(User, profile=profile)
    assert user.profile == profile

    user = mixer.blend(User, score=mixer.RANDOM)
    assert user.score != 50

    user = mixer.blend(User, username=lambda: 'callable_value')
    assert user.username == 'callable_value'
Example #8
0
def test_mixer(session):
    from mixer.backend.sqlalchemy import Mixer

    mixer = Mixer(session=session, commit=True)
    p = mixer.blend('tests.test_sqlalchemy.ProfileNonIncremental', id=5)
    role = mixer.blend('tests.test_sqlalchemy.Role', user__profile_id_nonincremental=p)
    assert role and role.user

    role = mixer.blend(Role, user__name='test2')
    assert role.user.name == 'test2'

    profile = mixer.blend('tests.test_sqlalchemy.Profile')
    user = mixer.blend(User, profile__name='test')
    assert user.profile.name == 'test'

    user = mixer.blend(User, profile=profile)
    assert user.profile == profile

    user = mixer.blend(User, score=mixer.RANDOM)
    assert user.score != 50

    user = mixer.blend(User, username=lambda: 'callable_value')
    assert user.username == 'callable_value'
Example #9
0
    def test_mixer(self):
        from mixer.backend.sqlalchemy import Mixer

        mixer = Mixer(session=self.session, commit=True)
        role = mixer.blend('tests.test_sqlalchemy.Role')
        self.assertTrue(role)
        self.assertTrue(role.user)

        role = mixer.blend(Role, user__name='test2')
        self.assertEqual(role.user.name, 'test2')

        profile = mixer.blend('tests.test_sqlalchemy.Profile')
        user = mixer.blend(User, profile__name='test')
        self.assertEqual(user.profile.name, 'test')

        user = mixer.blend(User, profile=profile)
        self.assertEqual(user.profile, profile)

        user = mixer.blend(User, score=mixer.random)
        self.assertNotEqual(user.score, 50)

        user = mixer.blend(User, username=lambda: 'callable_value')
        self.assertEqual(user.username, 'callable_value')
Example #10
0
    def test_mixer(self):
        from mixer.backend.sqlalchemy import Mixer

        mixer = Mixer(session=self.session, commit=True)
        role = mixer.blend('tests.test_sqlalchemy.Role')
        self.assertTrue(role)
        self.assertTrue(role.user)

        role = mixer.blend(Role, user__name='test2')
        self.assertEqual(role.user.name, 'test2')

        profile = mixer.blend('tests.test_sqlalchemy.Profile')
        user = mixer.blend(User, profile__name='test')
        self.assertEqual(user.profile.name, 'test')

        user = mixer.blend(User, profile=profile)
        self.assertEqual(user.profile, profile)

        user = mixer.blend(User, score=mixer.random)
        self.assertNotEqual(user.score, 50)

        user = mixer.blend(User, username=lambda: 'callable_value')
        self.assertEqual(user.username, 'callable_value')
Example #11
0
class Faker:
    """
    Class for automatic filling the database with test data

    """
    def __init__(self, models: Models, verbose=False, fake=False, db=None):
        self._models = models
        self._config = Config()
        self._verbose = verbose
        self._mixer = None
        self._fake = fake
        self._silence_system_warn = False
        self._max_resolve = 20

        if db:
            self._init_mixer(db)

    def _init_mixer(self, db):
        self._mixer = Mixer(session=db, commit=False, fake=self._fake)

    def fake_all(self, default_num=5):
        """Fill the database with fake data

        :param default_num: number of entries per table
        """
        schemas = list(self._models.schemas.keys())
        if 'system' in schemas:
            self.fake_schema('system', default_num=default_num)
            schemas.remove('system')
            self._silence_system_warn = True
        for schema in schemas:
            self.fake_schema(schema, default_num=default_num)
        self._silence_system_warn = False

    def fake_schema(self, schema, entries={}, default_num=5):
        """Fill the database schema tables with fake data

        raises ResolveError if could not resolve foreign keys

        :param schema: schema name
        :param entries: {model_name: number_of_entries}
        model_name is generated camelCase
        :param default_num: number of entries, if t_name is not in entries
        """
        if 'system' in self._models.schemas and not self._silence_system_warn:
            logging.warning('If the model has references to system tables, '
                            'it may be required to fake schema `system` first')
        generated = {name: 0 for name in self._models[schema].keys()}
        not_resolved = {name: 0 for name in self._models[schema].keys()}
        if schema in self._config.Faker['ignore']:
            for key in self._config.Faker['ignore'][schema]:
                del generated[key]
                del not_resolved[key]

        total = sum([
            entries.get(name, default_num)
            for name in self._models[schema].keys()
        ])
        try:
            if self._verbose:
                bar = tqdm.tqdm(total=total)

            with DBConn.get_session(autoflush=False) as db:
                self._init_mixer(db)
                while len(generated) > 0:
                    finished = []
                    for name, i in generated.items():
                        if i >= entries.get(name, default_num):
                            finished.append(name)
                            continue

                        model = self._models[schema][name]
                        if self._fake_model(model, db):
                            generated[name] += 1
                            if self._verbose:
                                bar.update(1)
                            not_resolved[name] = 0
                        else:
                            not_resolved[name] += 1
                            if not_resolved[name] > self._max_resolve:
                                raise ResolveError(
                                    f"Can't resolve foreign keys for {name}")
                    for name in finished:
                        del generated[name]
                    self._flush_faked(db)

        finally:
            if self._verbose:
                bar.close()

    def fake_one(self, model, db):
        """Generate fake model

        :param model: SQLAlchemy model
        :param db: session, connection or engine
        :returns: model instance, if fks were resolved successfully
        """
        attributes = {}
        resolved = True
        relationships = inspect(model).relationships.values()
        for name, attr in dict(model.__table__.columns).items():
            if attr.foreign_keys:
                fk = next(iter(attr.foreign_keys))
            else:
                continue
            t_name = '.'.join(fk._column_tokens[:-1])
            # backref_name = fk._column_tokens[1]
            column = fk._column_tokens[-1]
            entry = list(
                db.execute(
                    f"SELECT {column} FROM {t_name} ORDER BY RANDOM() LIMIT 1")
            )
            if not entry:
                resolved = False
                break
            else:
                attributes[name] = entry[0][0]
                rel = self._get_relationship(relationships, name)
                if rel:
                    name = NamesConverter.class_name(rel.target.schema,
                                                     rel.target.name)
                    target = self._models[rel.target.schema][name]
                    search = {}
                    search[column] = entry[0][0]
                    obj = db.query(target).filter_by(**search).first()
                    attributes[rel.class_attribute.key] = obj
        if resolved:
            faked = self._mixer.blend(model, **attributes)
            return faked
        return None

    def _flush_faked(self, db):
        try:
            db.commit()
        except sa.exc.IntegrityError:
            db.rollback()  # TODO logging

    def _fake_model(self, model, db):
        faked = self.fake_one(model, db)
        if faked:
            db.add(faked)
            return True
        return False

    def _get_relationship(self, relationships, column_name):
        for r in relationships:
            if any([c.name == column_name for c in r.local_columns]):
                return r

    def faked_models(self):
        models = []
        for schema in self._models.schemas.keys():
            if schema not in self._config.Faker['ignore']:
                models.extend(self._models[schema].values())
            else:
                for key, model in self._models[schema].items():
                    if key not in self._config.Faker['ignore'][schema]:
                        models.append(model)
        return models