396 Stimmen

Wie konvertiert man ein SQLAlchemy-Zeilenobjekt in ein Python-Diktat?

Gibt es eine einfache Möglichkeit, über Spaltennamen- und -wertepaare zu iterieren?

Meine Version von SQLAlchemy ist 0.5.6

Hier ist der Beispielcode, in dem ich versucht habe, mit dict(row) :

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)

Die Ausführung dieses Codes auf meinem System ergibt:

Traceback (most recent call last):
  File "untitled-1.py", line 37, in <module>
    print dict(u)
TypeError: 'User' object is not iterable

365voto

hllau Punkte 8821

Sie können auf die internen __dict__ eines SQLAlchemy-Objekts, wie das folgende:

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

206voto

Alex Brasetvik Punkte 10472

Wie von @zzzeek in den Kommentaren erwähnt:

beachten Sie, dass dies die richtige Antwort für moderne Versionen von SQLAlchemy ist, vorausgesetzt "row" ist ein Core-Row-Objekt und keine ORM-mapped Instanz.

for row in resultproxy:
    row_as_dict = row._mapping  # SQLAlchemy 1.4 and greater
    # row_as_dict = dict(row)  # SQLAlchemy 1.3 and earlier

Hintergrund zu row._mapping neu ab SQLAlchemy 1.4: https://docs.sqlalchemy.org/en/stable/core/connections.html#sqlalchemy.engine.Row._mapping

195voto

Anurag Uniyal Punkte 81337

Ich konnte keine gute Antwort bekommen, also benutze ich das hier:

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

    return d

Edit: falls die obige Funktion zu lang und für manche Geschmäcker nicht geeignet ist, hier ein One-Liner (Python 2.7+)

row2dict = lambda r: {c.name: str(getattr(r, c.name)) for c in r.__table__.columns}

121voto

RazerM Punkte 4760

In SQLAlchemy v0.8 und neuer verwenden Sie die Kontrollsystem .

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)

Beachten Sie, dass .key ist der Attributname, der sich vom Spaltennamen unterscheiden kann, z. B. im folgenden Fall:

class_ = Column('class', Text)

Diese Methode funktioniert auch für column_property .

61voto

balki Punkte 24248

Zeilen haben eine _asdict() Funktion, die ein Diktat ergibt

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'}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X