Something like this should work. We can use itertools.groupby to group results by the value of item
, and tools from the operator module to abstract finding and extracting values.
import itertools
import operator
import pprint
import sqlalchemy as sa
from sqlalchemy import orm
Base = orm.declarative_base()
# Assuming this model strcuture
class MyModel(Base):
__tablename__ = 't74781694'
id = sa.Column(sa.Integer, primary_key=True)
item = sa.Column(sa.String)
attribute_id = sa.Column(sa.String)
attribute_value = sa.Column(sa.String)
attribute_name = sa.Column(sa.String)
engine = sa.create_engine('sqlite://', echo=True, future=True)
Base.metadata.create_all(engine)
Session = orm.sessionmaker(engine, future=True)
# The attributes that we want to group.
keys = ['attribute_id', 'attribute_value', 'attribute_name']
# ORM solution (using model entities).
attrgetter = operator.attrgetter(*keys)
with Session() as s:
instances = s.scalars(sa.select(MyModel))
data = [
(k, [dict.fromkeys(keys, attrgetter(g)) for g in grouped])
for k, grouped in itertools.groupby(instances, key=lambda m: m.item)
]
pprint.pprint(data)
# Hybrid core/ORM solution (Using session and table).
# Pure core would entail using engine instead of session
keygetter = operator.itemgetter('item')
itemgetter = operator.itemgetter(*keys)
with Session() as s:
tbl = MyModel.__table__
rows = s.execute(sa.select(tbl)).mappings()
data = [
(k, [dict.fromkeys(keys, itemgetter(g)) for g in grouped])
for k, grouped in itertools.groupby(rows, key=keygetter)
]
pprint.pprint(data)