Source

djsqlalchemy / djsqlalchemy / mapper.py

from django.db.models import ForeignKey

from djsqlalchemy.alchemy import get_engine


__all__ = ['fetchall', 'get_list', 'get_one']


def map_related(obj, values, prefix=''):
    # special case for master obj
    local_prefix = prefix or (obj._meta.db_table + '_')

    fks = []
    for field in obj._meta.local_fields:
        if isinstance(field, ForeignKey):
            fks.append(field)
        else:
            label = local_prefix + field.name
            if label in values:
                setattr(obj, field.name, values[label])
                del values[label]

    if obj.pk:
        for fk in fks:
            rel_obj = fk.rel.to()
            map_related(rel_obj, values, prefix=prefix + fk.name + '_')
            if rel_obj.pk:
                cache_name = '_%s_cache' % fk.name
                setattr(obj, cache_name, rel_obj)


def map_values(model, values):
    obj = model()

    # TODO: replace with values = dict(values)
    d = {}
    for i, key in enumerate(values.keys()):
        d[key] = values._row[i]
    values = d

    map_related(obj, values)

    # set other values on master obj as is
    for label, value in values.items():
        setattr(obj, label, value)
    return obj


def fetchall(s, model=None):
    engine = get_engine()

    result = engine.execute(s)
    values_list = result.fetchall()

    for values in values_list:
        if model:
            yield map_values(model, values)
        else:
            yield values


def get_list(s, model=None):
    return list(fetchall(s, model))


def get_one(s, model=None):
    objs = list(fetchall(s, model))

    if not objs:
        if model:
            raise model.DoesNotExist()
        else:
            raise ValueError('Query returned empty result')
    elif len(objs) > 1:
        if model:
            raise model.MultipleObjectsReturned()
        else:
            raise ValueError('Query returned multiple rows')

    return objs[0]
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.