Ejemplo n.º 1
0
    async def fetch_many(cls, query=None, filter_by=None):
        from asyncpgsa import pg

        columns = [*cls.c, *cls.to_many_selectables]

        filter_expressions = []
        result = []

        if filter_by is not None:
            for column_name, filter_rule in filter_by.items():
                try:
                    column = getattr(cls.c, column_name)
                except AttributeError:
                    raise ValueError(f'Table `{cls.table.name}` does not '
                                     f'contain column `{column_name}`')

                filter_expressions.append((column == filter_rule))

        if query is None:
            query = cls.query()

        if filter_expressions:
            query = query.where(sa.and_(*filter_expressions))

        if len(cls._to_many_relations):
            query = query.group_by(cls.pk_column)

        query = query.with_only_columns(columns)

        async with pg.query(query) as cursor:
            async for row in cursor:
                resource = cls.from_row(row, columns=columns)
                result.append(resource)
        return result
Ejemplo n.º 2
0
async def test_pg_queury_with_await():
    ps = pg.query(query)
    results = await ps
    row = sentinel = object()
    for row in results:
        assert row['a'] == 4.0
        assert row['b'] == 6.0
        assert row['c'] == 5.0
    if row is sentinel:
        pytest.fail('No results')
Ejemplo n.º 3
0
async def test_pg_query_async_with_statement():
    ps = pg.query(query)
    async with ps as cursor:
        row = sentinel = object()
        async for row in cursor:
            assert row['a'] == 4.0
            assert row['b'] == 6.0
            assert row['c'] == 5.0
        if row is sentinel:
            pytest.fail('Cursor had no data')
Ejemplo n.º 4
0
async def test_pg_queury_with_await():
    ps = pg.query(query)
    results = await ps
    row = sentinel = object()
    for row in results:
        assert row['a'] == 4.0
        assert row['b'] == 6.0
        assert row['c'] == 5.0
    if row is sentinel:
        pytest.fail('No results')
Ejemplo n.º 5
0
async def test_pg_query_async_with_statement():
    ps = pg.query(query)
    async with ps as cursor:
        row = sentinel = object()
        async for row in cursor:
            assert row['a'] == 4.0
            assert row['b'] == 6.0
            assert row['c'] == 5.0
        if row is sentinel:
            pytest.fail('Cursor had no data')
Ejemplo n.º 6
0
async def test_pg_query_async_with_statement():
    await _init()

    ps = pg.query(query)
    async with ps as cursor:
        async for row in cursor:
            assert row.a == 4.0
            assert row.b == 6.0
            assert row.c == 5.0
            result = 2

        assert result == 2
Ejemplo n.º 7
0
async def test_pg_query_with_bad_with_statement():
    ps = pg.query(query)

    with pytest.raises(RuntimeError) as exc_info:
        with ps as cursor:
            async for row in cursor:
                assert row['a'] == 4.0
                assert row['b'] == 6.0
                assert row['c'] == 5.0

            result = 2

        assert result == 2

    assert str(exc_info.value) == 'Must use "async with"'
Ejemplo n.º 8
0
async def test_pg_query_with_bad_with_statement():
    ps = pg.query(query)

    with pytest.raises(RuntimeError) as exc_info:
        with ps as cursor:
            async for row in cursor:
                assert row['a'] == 4.0
                assert row['b'] == 6.0
                assert row['c'] == 5.0

            result = 2

        assert result == 2

    assert str(exc_info.value) == 'Must use "async with"'
Ejemplo n.º 9
0
async def test_pg_query_with_bad_with_statement():
    await _init()

    ps = pg.query(query)
    try:
        with ps as cursor:
            async for row in cursor:
                assert row.a == 4.0
                assert row.b == 6.0
                assert row.c == 5.0

            result = 2

        assert result == 2

        # try:
        # event_loop.run_until_complete(async_with())
        raise Exception('Should have thrown exception')
    except SyntaxError as e:
        assert str(e) == 'Must use "async with"'
Ejemplo n.º 10
0
async def test_pg_query_with_no_results():
    ps = pg.query("SELECT * FROM pg_tables WHERE tablename='bob'")
    async with ps as cursor:
        async for row in cursor:
            raise Exception('Should not have hit this line')
Ejemplo n.º 11
0
async def get_collection(args, *models, **kwargs):
    """
    Fetch a heterogeneous collection of objects.

    Returns a heterogeneous list of objects.

    >>> from jsonapi.model import search
    >>> search({'include[user]': 'bio',
    >>>         'include[article]': 'keywords,author.bio,publisher.bio',
    >>>         'fields[user]': 'name,email',
    >>>         'fields[user-bio]': 'birthday,age',
    >>>         'fields[article]': 'title'},
    >>>         'John', UserModel, ArticleModel)

    :param dict args: a dictionary representing the request query string
    :param mixed models: variable length list of model classes or instances
    :param str search: a PostgreSQL full text search query string (e.x. ``'foo:* & !bar'``)
    :return: JSON API response document
    """
    ra = parse_arguments(args)
    search_term = kwargs.pop('search', None) or args.pop('search', None)
    models = ModelSet(*models, searchable=search_term is not None)
    query = select_mixed(models, order_by=ra.sort, limit=ra.page.limit, offset=ra.page.offset) \
        if search_term is None else search_query(models, search_term, limit=ra.page.limit, offset=ra.page.offset)
    log_query(query)
    mixed = list()
    async with pg.query(query) as cursor:
        async for row in cursor:
            mixed.append(dict(type=row['resource_type'], id=row['id']))

    data = defaultdict(dict)
    included = defaultdict(dict)
    meta = {'total': 0, 'subTotal': dict()}
    for model in models:
        object_id = list(obj['id'] for obj in mixed
                         if model.type_ == obj['type'])
        if len(object_id) > 0:
            model_args = model.parse_arguments(_extract_model_args(
                model, args))
            model.init_schema(model_args)
            query = select_many(model,
                                filter_by=FilterBy(
                                    model.primary_key.in_([
                                        cast(x, model.primary_key.type)
                                        for x in object_id
                                    ])))
            log_query(query)
            recs = [{
                'type': model.type_,
                **rec
            } for rec in await pg.fetch(query)]
            await model.fetch_included(recs, model_args)
            for rec in model.schema.dump(recs, many=True):
                data[rec['type']][rec['id']] = rec
            if len(model.included) > 0:
                for resource_type in model.included.keys():
                    included[resource_type].update(
                        model.included[resource_type])
        model.reset()

    for (resource_type, query) in (select_mixed(models, count=True) \
            if search_term is None else search_query(models, search_term, count=True)):
        meta['subTotal'][resource_type] = await pg.fetchval(query)
        meta['total'] += meta['subTotal'][resource_type]
    return dict(data=[data[rec['type']][str(rec['id'])] for rec in mixed],
                included=reduce(lambda a, b: a + [r for r in b.values()],
                                included.values(), list()),
                meta=meta)
Ejemplo n.º 12
0
async def test_pg_query_with_no_results():
    ps = pg.query("SELECT * FROM pg_tables WHERE tablename='bob'")
    async with ps as cursor:
        async for row in cursor:
            raise Exception('Should not have hit this line')