将sqlalchemy行对象转换为python dict
有没有一种简单的方法可以迭代列名和值对 我的sqlalchemy版本是0.5.6 下面是我尝试使用dict(行)的示例代码,但它抛出异常TypeError:“User”对象不可编辑将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
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
开头标记列,以指示您希望隐藏它们,这可能是因为您通过混合属性访问属性,也可能是因为您不想显示它们
Tippall\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'}