将sqlalchemy行对象转换为python dict

将sqlalchemy行对象转换为python dict,python,sqlalchemy,Python,Sqlalchemy,有没有一种简单的方法可以迭代列名和值对 我的sqlalchemy版本是0.5.6 下面是我尝试使用dict(行)的示例代码,但它抛出异常TypeError:“User”对象不可编辑 import sqlalchemy from sqlalchemy import * from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker print "sqlalchemy v

有没有一种简单的方法可以迭代列名和值对

我的sqlalchemy版本是0.5.6

下面是我尝试使用dict(行)的示例代码,但它抛出异常TypeError:“User”对象不可编辑

import sqlalchemy
from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

print "sqlalchemy version:",sqlalchemy.__version__ 

engine = create_engine('sqlite:///:memory:', echo=False)
metadata = MetaData()
users_table = Table('users', metadata,
     Column('id', Integer, primary_key=True),
     Column('name', String),
)
metadata.create_all(engine) 

class User(declarative_base()):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String)

    def __init__(self, name):
        self.name = name

Session = sessionmaker(bind=engine)
session = Session()

user1 = User("anurag")
session.add(user1)
session.commit()

# uncommenting next line throws exception 'TypeError: 'User' object is not iterable'
#print dict(user1)
# this one also throws 'TypeError: 'User' object is not iterable'
for u in session.query(User).all():
    print dict(u)
在我的系统输出上运行此代码:

sqlalchemy version: 0.5.6
Traceback (most recent call last):
  File "untitled-1.py", line 37, in <module>
    print dict(u)
TypeError: 'User' object is not iterable
sqlalchemy版本:0.5.6
回溯(最近一次呼叫最后一次):
文件“untitled-1.py”,第37行,在
打印命令(u)
TypeError:“用户”对象不可编辑

根据注释中的@zzzeek:


请注意,这是现代版本的的正确答案 SQLAlchemy,假设“行”是核心行对象,而不是ORM映射的对象 例如


我无法得到一个好的答案,因此我使用以下方法:

def row2dict(row):
    d = {}
    for column in row.__table__.columns:
        d[column.name] = str(getattr(row, column.name))

    return d
编辑:如果上面的函数太长并且不适合某些口味,那么这里有一个单行程序(python 2.7+)


您正在迭代的表达式的计算结果是模型对象列表,而不是行。因此,以下是它们的正确用法:

for u in session.query(User).all():
    print u.id, u.name
你真的需要把它们转换成口述吗?当然,有很多方法,但是您不需要ORM作为SQLAlchemy的一部分:

result = session.execute(User.__table__.select())
for row in result:
    print dict(row)
更新:查看
sqlalchemy.orm.attributes
模块。它有一组用于处理对象状态的函数,这可能对您很有用,尤其是
instance\u dict()


这应该行得通。

我对马可·马里亚尼的回答有一个不同的说法,用一个装饰师的话来表达。主要区别在于它将处理实体列表,并安全地忽略一些其他类型的返回值(这在使用mock编写测试时非常有用):

from sqlalchemy.orm import class_mapper

def asdict(obj):
    return dict((col.name, getattr(obj, col.name))
                for col in class_mapper(obj.__class__).mapped_table.c)

以下是长生不老药的作用。这个解决方案的价值在于它允许递归地包含关系的字典表示

def to_dict(self,deep={},exclude=[]):
“”“从对象生成JSON样式的嵌套dict/list结构。”“”
col_prop_names=[p.key代表self.mapper.iterate_属性中的p\
如果isinstance(p,ColumnProperty)]
data=dict([(名称,getattr(self,name))
用于列中的名称(如果名称不在排除中,则为名称)
对于rname,rdeep在深处。iteritems():
dbdata=getattr(self,rname)
#修复方法:使用属性名(即coltoprop)而不是列名
fks=self.mapper.get_属性(rname).remote_端
exclude=[fks中c的c.name]
如果dbdata为无:
数据[rname]=无
elif isinstance(数据库数据,列表):
数据[rname]=[o.to_dict(rdeep,exclude)表示dbdata中的o]
其他:
数据[rname]=dbdata.to_dict(rdeep,exclude)
返回数据

您可以访问SQLAlchemy对象的内部
\uuuu dict\uuuu
,如下所示:

for u in session.query(User).all():
    print u.__dict__

我找到这篇文章是因为我正在寻找一种将SQLAlchemy行转换为dict的方法。我正在使用SqlSoup。。。但答案是我自己创造的,因此,如果它能帮助某人,这是我的两分钱:

a = db.execute('select * from acquisizioni_motes')
b = a.fetchall()
c = b[0]

# and now, finally...
dict(zip(c.keys(), c.values()))
行具有一个
\u asdict()
函数,该函数提供一个dict

In [8]: r1 = db.session.query(Topic.name).first()

In [9]: r1
Out[9]: (u'blah')

In [10]: r1.name
Out[10]: u'blah'

In [11]: r1._asdict()
Out[11]: {'name': u'blah'}
正如@balki所提到的:

如果要查询特定字段,则可以使用
\u asdict()
方法,因为该字段是作为字段返回的

然而,如果不指定列,则可以使用其他建议的方法之一,例如@charlax提供的方法。请注意,此方法仅对2.7+有效

In [1]: foo = db.session.query(Topic).first()
In [2]: {x.name: getattr(foo, x.name) for x in foo.__table__.columns}
Out[2]: {'name': u'blah'}

在@balki answer之后,自SQLAlchemy 0.8以来,您可以使用
\u asdict()
,可用于
KeyedTuple
对象。这就为最初的问题提供了一个非常简单的答案。只需将示例中的最后两行(for循环)更改为这一行:

for u in session.query(User).all():
   print u._asdict()
这是因为在上面的代码中,
u
是class类型的对象,因为
.all()
返回
KeyedTuple
的列表。因此它有一个方法,可以很好地将u作为字典返回


用@STB:AFAIK写出答案,
.all()
返回的任何内容都是
KeypedTuple
的列表。因此,如果指定列或不指定列,只要处理应用于
查询
对象的
.all()
的结果,上述操作就有效。

假设将以下函数添加到
类用户
中,则以下操作将返回所有列的所有键值对:

def columns_to_dict(self):
    dict_ = {}
    for key in self.__mapper__.c.keys():
        dict_[key] = getattr(self, key)
    return dict_
与其他答案不同,只返回对象的所有属性,这些属性是对象类级别的属性。因此,不包括
\u sa\u instance\u state
或添加到对象的任何其他属性SQLalchemy

编辑:忘了说,这也适用于继承的列

hybrid_属性
extension 如果您还希望包括
hybrid\u属性
属性,则以下操作将起作用:

from sqlalchemy import inspect
from sqlalchemy.ext.hybrid import hybrid_property

def publics_to_dict(self) -> {}:
    dict_ = {}
    for key in self.__mapper__.c.keys():
        if not key.startswith('_'):
            dict_[key] = getattr(self, key)

    for key, prop in inspect(self.__class__).all_orm_descriptors.items():
        if isinstance(prop, hybrid_property):
            dict_[key] = getattr(self, key)
    return dict_
在这里,我假设您以
\uuu
开头标记列,以指示您希望隐藏它们,这可能是因为您通过
混合属性访问属性,也可能是因为您不想显示它们

Tipp
all\u orm\u descriptor
也会返回,如果您还想包含它们

对其他答案的评论 基于
\u dict\u
属性的每个答案(比如,)都只返回对象的所有属性。这可能比您想要的属性多得多。就像我所说的,这包括
\u sa\u instance\u state
或您在此对象上定义的任何其他属性

基于
dict()
函数的每个答案(如,)仅适用于
session.execute()
返回的SQLalchemy行对象,而不适用于您定义要使用的类,如问题中的
类用户

基于
行.\u表.\u列
的方法肯定不会起作用<代码>行。\表\列
包含SQL数据库的列名。这些属性只能等于python对象的属性名称。如果不是,则会得到一个
属性错误
。
对于answ
In [1]: foo = db.session.query(Topic.name).first()
In [2]: foo._asdict()
Out[2]: {'name': u'blah'}
In [1]: foo = db.session.query(Topic).first()
In [2]: {x.name: getattr(foo, x.name) for x in foo.__table__.columns}
Out[2]: {'name': u'blah'}
for u in session.query(User).all():
   print u._asdict()
def columns_to_dict(self):
    dict_ = {}
    for key in self.__mapper__.c.keys():
        dict_[key] = getattr(self, key)
    return dict_
from sqlalchemy import inspect
from sqlalchemy.ext.hybrid import hybrid_property

def publics_to_dict(self) -> {}:
    dict_ = {}
    for key in self.__mapper__.c.keys():
        if not key.startswith('_'):
            dict_[key] = getattr(self, key)

    for key, prop in inspect(self.__class__).all_orm_descriptors.items():
        if isinstance(prop, hybrid_property):
            dict_[key] = getattr(self, key)
    return dict_
def sqlAl2json(self, result):
    arr = []
    for rs in result.all():
        proc = []
        try:
            iterator = iter(rs)
        except TypeError:
            proc.append(rs)
        else:
            for t in rs:
                proc.append(t)

        dict = {}
        for p in proc:
            tname = type(p).__name__
            for d in dir(p):
                if d.startswith('_') | d.startswith('metadata'):
                    pass
                else:
                    key = '%s_%s' %(tname, d)
                    dict[key] = getattr(p, d)
        arr.append(dict)
    return json.dumps(arr)
from sqlalchemy import inspect

def object_as_dict(obj):
    return {c.key: getattr(obj, c.key)
            for c in inspect(obj).mapper.column_attrs}

user = session.query(User).first()

d = object_as_dict(user)
class_ = Column('class', Text)
rows = conn.execute(query)
list_of_dicts = [dict((key, value) for key, value in row.items()) for row in rows]
rows = conn.execute(query)
list_of_dicts = [{key: value for (key, value) in row.items()} for row in rows]
row_as_dict = [dict(row) for row in resultproxy]
query = session.query(User)
def query_to_dict(query):
        def _create_dict(r):
            return {c.get('name'): getattr(r, c.get('name')) for c in query.column_descriptions}

    return [_create_dict(r) for r in query]
for row in session.execute(session.query(User).statement):
    print(dict(row))
selected_columns = User.__table__.columns
rows = session.query(User).with_entities(*selected_columns).all()
for row in rows :
    print(row._asdict())
import json
from collections import OrderedDict


def asdict(self):
    result = OrderedDict()
    for key in self.__mapper__.c.keys():
        if getattr(self, key) is not None:
            result[key] = str(getattr(self, key))
        else:
            result[key] = getattr(self, key)
    return result


def to_array(all_vendors):
    v = [ ven.asdict() for ven in all_vendors ]
    return json.dumps(v) 
def all_products():
    all_products = Products.query.all()
    return to_array(all_products)
class People:
    id: int = Column(name='id', type_=Integer, primary_key=True)
    createdTime: datetime = Column(name='create_time', type_=TIMESTAMP,
                               nullable=False,
                               server_default=text("CURRENT_TIMESTAMP"),
                               default=func.now())
    modifiedTime: datetime = Column(name='modify_time', type_=TIMESTAMP,
                                server_default=text("CURRENT_TIMESTAMP"),
                                default=func.now())
 from sqlalchemy.orm import class_mapper 
 def asDict(self):
        return {x.key: getattr(self, x.key, None) for x in
            class_mapper(Application).iterate_properties}
{'id': 1, 'create_time': None, 'modify_time': None}


    def to_dict(self):
        return {c.name: getattr(self, c.name, None)
         for c in self.__table__.columns}
def to_array(rows):
    return [r._asdict() for r in rows]

def query():
    data = session.query(Table).all()
    return to_array(data)
In [46]: result = aggregate_events[0]

In [47]: type(result)
Out[47]: sqlalchemy.util._collections.result

In [48]: def to_dict(query_result=None):
    ...:     cover_dict = {key: getattr(query_result, key) for key in query_result.keys()}
    ...:     return cover_dict
    ...: 
    ...:     

In [49]: to_dict(result)
Out[49]: 
{'calculate_avg': None,
 'calculate_max': None,
 'calculate_min': None,
 'calculate_sum': None,
 'dataPointIntID': 6,
 'data_avg': 10.0,
 'data_max': 10.0,
 'data_min': 10.0,
 'data_sum': 60.0,
 'deviceID': u'asas',
 'productID': u'U7qUDa',
 'tenantID': u'CvdQcYzUM'}
def run_sql(conn_String):
  output_connection = engine.create_engine(conn_string, poolclass=NullPool).connect()
  rows = output_connection.execute('select * from db1.t1').fetchall()  
  return [dict(row) for row in rows]
for u in session.query(User).all():
    print(u._asdict())
def to_dict(row):
    return {column.name: getattr(row, row.__mapper__.get_property_by_column(column).key) for column in row.__table__.columns}


for u in session.query(User).all():
    print(to_dict(u))
from sqlalchemy.inspection import inspect

def to_dict(obj, with_relationships=True):
    d = {}
    for column in obj.__table__.columns:
        if with_relationships and len(column.foreign_keys) > 0:
             # Skip foreign keys
            continue
        d[column.name] = getattr(obj, column.name)

    if with_relationships:
        for relationship in inspect(type(obj)).relationships:
            val = getattr(obj, relationship.key)
            d[relationship.key] = to_dict(val) if val else None
    return d

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    first_name = Column(TEXT)
    address_id = Column(Integer, ForeignKey('addresses.id')
    address = relationship('Address')

class Address(Base):
    __tablename__ = 'addresses'
    id = Column(Integer, primary_key=True)
    city = Column(TEXT)


user = User(first_name='Nathan', address=Address(city='Lyon'))
# Add and commit user to session to create ids

to_dict(user)
# {'id': 1, 'first_name': 'Nathan', 'address': {'city': 'Lyon'}}
to_dict(user, with_relationship=False)
# {'id': 1, 'first_name': 'Nathan', 'address_id': 1}
def queryset_to_dict(query_result):
   query_columns = query_result[0].keys()
   res = [list(ele) for ele in query_result]
   dict_list = [dict(zip(query_columns, l)) for l in res]
   return dict_list

query_result = db.session.query(LanguageMaster).all()
dictvalue=queryset_to_dict(query_result)
Base = declarative_base(cls=DictableModel)

session.query(User).asdict()
{'id': 1, 'username': 'Gerald'}

session.query(User).asdict(exclude=['id'])
{'username': 'Gerald'}