I have the table soldiers:
class Soldier(Base):
__tablename__ = "soldiers"
id = Column(String(36), default=lambda: str(uuid4()), primary_key=True, unique=True)
name = Column(String(50), nullable=False)
service_number = Column(Integer, nullable=False)
commander_id = Column(String(36), nullable=False, index=True)
created_at = Column(Date, nullable=False, default=func.now())
and this async query:
result = await db.execute(select(Soldier))
soldiers = result.scalars().all()
db comes from here:
async def get_db():
async with engine.begin() as connection:
await connection.run_sync(Base.metadata.create_all)
db = AsyncSession()
try:
print("connection opened")
yield db
finally:
print("connection closed")
await db.close()
For the problem itself. How do I query only for specific columns? I’m using a MySQL db hosted on planetscale (vitess)
The result when trying this is a list of the first column argument, say its id – so I get an array of id’s in the response:
result = await db.execute(select(Soldier.id, Soldier.name, Soldier.service_number))
soldiers = result.scalars().all()
also tried using this but same result:
result = await db.execute(select(Soldier).with_only_columns(Soldier.id, Soldier.name, Soldier.service_number))
soldiers = result.scalars().all()
2
Answers
When you use
Session.scalars()
, it will deliver the first "column" of eachrow. If your
select()
is on a model, such asselect(Soldier)
, it will returna list of tuples of the form:
(Soldier(...),)
(a one element tuple with thesoldier object), so using
.scalars()
will return a list ofSoldier
objects.Session.scalars()
is a convenience method for this case.But when you selected specific columns (like
select(Soldier.id, Soldier.name, Soldier.service_number)
), you will want touse the result directly, since a list of tuples of the form
(id, name, service_number)
will be returned. If you usedscalars
on it, youwill only get the first column, which is
id
here.you can try this:
put your prefered columns on the satement