sqlalchemy,alchimia并从原始查询创建对象

时间:2016-02-24 08:14:51

标签: python asynchronous orm sqlalchemy

我正在使用alchimia异步使用SQLAlchemy的强大功能。

我遇到的唯一问题是从原始查询构建对象变得单调乏味,有没有一种方法可以使用ORM的SQLAlchemy 构建对象而不实际使用ORM本身?

例如,假设我在alchimia dox示例中有一个user表:

users = Table("users", metadata,
    Column("id", Integer(), primary_key=True),
    Column("name", String()),
)

我查询它以检索所有用户:

result = yield engine.execute(users.select())

我想返回模型实例而不是dict,所以我创建了一个简单的构建器:

class BaseModel(object, pythonutil.FancyEqMixin,
                pb.Copyable, pb.RemoteCopy):
    compareAttributes = ('id',)
    tbl = None

    def __init__(self, *args, **kwargs):
        for arg in args:
            if isinstance(arg, dict):
                for k, v in arg.items():
                    setattr(self, k, v)

        if kwargs:
            for k, v in kwargs.items():
                setattr(self, k, v)

    @classmethod
    def build(cls, resource, alias=None):

        assert (isinstance(cls.tbl, sa.Table)), \
            "Model's '.tbl' property must be a sqlalchemy.schema.Table"

        if isinstance(resource, tuple):
            resource = resource[0]
        resource = dict(resource)
        if alias is not None:
            from sqlalchemy.sql import expression
            alias = (alias.name if
                     isinstance(alias, expression.Alias)
                     else str(alias))
        else:
            alias = cls.tbl.name
        rawdata = dict()
        for (k, v) in resource.items():
            if not k.startswith(alias):
                continue
            # remove the alias from the columns name, some tables
            # may have underscores in their name, so count the occurrence
            # of "_" i the alias ( = tablename) and get the string after it
            # e.g. "module_server_module_ipaddr" becomes "module_ipaddr"
            _k = '_'.join(k.split('_')[1 + alias.count('_'):])
            try:
                # try to get the column from table, on fail skip
                cls.tbl.c[_k]
            except KeyError:
                continue
            rawdata[_k] = v

        return cls(**rawdata)

    def update(self, other):
        assert isinstance(other, BaseModel), \
            "other should be %r, %r given" % (BaseModel, other)
        for k, v in other.__dict__.items():
            setattr(self, k, v)

    def __setitem__(self, key, value):
        return setattr(self, key, value)

    def __getitem__(self, item):
        return getattr(self, item)

此对象的工作方式类似于字典,但可以使用原始查询数据构建,这里是模型示例:

class User(BaseModel):
    tbl = user_tbl

我可以定义像SQLAlchemy ORM那样的模型,使用sqlalchemy core查询数据库,然后使用查询数据构建模型吗?

0 个答案:

没有答案