自己手写SQL通过SQLAlchemy查询返回了ProxyResult,再怎么把ProxyResult转变为表对象?

我是SQLAlchemy的初学者,很多时候还只会用纯SQL来写查询,但是这样查询出来的是RowProxy对象:

sql = 'SELECT user_id, account, user_type FROM user WHERE account = :account'
result = db_session.execute(sql, dict(account='john')).fetchone()
print type(result)

<class 'sqlalchemy.engine.result.RowProxy'>

我想请教熟悉SQLAlchemy的前辈,有没有一个现成的方法可以将返回的RowProxy变成我定义好的表对象?

当然,对于上面这个简单的查询,我知道可以通过使用ORM的方式来获得对象:

db_session.query(User).filter(User.account == 'john').first()

<models.User object at 0x0CEC13D0>

但是正如我上面说的,SQLAlchemy有没有提供将RowProxy对象转换为实体对象的方法?

阅读 14k
5 个回答

没有直接的方法。
因为RowProxy里面保存的就是一个column name到column value的dict,你可以取出所有的column构造一个model对象就好了。

新手上路,请多包涵

试试这个

https://github.com/harryliu/pyDbRowFactory

原作者blog

http://www.cnblogs.com/harrychinese/archive/2011/11/10/2244756.html

class _Base(object):
    @classmethod
    def proxy_to_obj(cls):
        obj = cls()

        cla = obj.__class__.__mro__
        # # 过滤不需要的父类
        cla = filter(lambda c: hasattr(c, '__table__'), filter(lambda c: isinstance(c, DeclarativeMeta), cla))
        columns = []
        map(lambda c: columns.extend(c.__table__.columns), cla[::-1])


        if isinstance(row, RowProxy):
            # 赋值
            for c in columns:
                if c.name in row:
                    setattr(obj, c.name, row[c.name])

        return obj

Base = declarative_base(cls=_Base)



class User(Base):
    pass

我一般把resut转成dict
dict((zip(result.keys(), result)))
然后需要合并到其他的对象的话,就做其他的操作,不需要的话,就直接用这个dict

这个其实很简单,官方API给出了接口,总有1个适合,注意first会关闭游标,即first操作后不要进行fetch操作,否则报错:
sqlalchemy.engine.result.ResultProxy.first
sqlalchemy.engine.result.ResultProxy.fetchone
sqlalchemy.engine.result.BufferedColumnResultProxy.fetchmany
sqlalchemy.engine.result.BufferedColumnResultProxy.fetchall

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题