The example I showed uses query.get(), or you can get a bunch of objects at once using session.query(). there's no need to use raw sql.
if OTOH you are trying to do this entirely on the SQL side then you can use a Core update() construct that assigns the array column using the Postgresql array concatenation operator. The example below illustrates how to do this both for all rows at once, and on a per-row basis, with no SELECT in use.
from sqlalchemy import ARRAY
from sqlalchemy import bindparam
from sqlalchemy import Column
from sqlalchemy import create_engine
from sqlalchemy import Integer
from sqlalchemy.dialects.postgresql import ARRAY
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import Session
Base = declarative_base()
class A(Base):
__tablename__ = "a"
id = Column(Integer, primary_key=True)
data = Column(ARRAY(Integer))
e = create_engine("postgresql://scott:tiger@localhost/test", echo=True)
Base.metadata.drop_all(e)
Base.metadata.create_all(e)
s = Session(e)
s.add_all(
[A(data=[1, 2, 3]), A(data=[4, 5, 6]), A(data=[7, 8, 9]),]
)
s.commit()
# example one - update all rows to the same value
s.query(A).update({"data": A.data + [10, 11, 12]}, synchronize_session=False)
assert list(s.query(A.data).order_by(A.id)) == [
([1, 2, 3, 10, 11, 12],),
([4, 5, 6, 10, 11, 12],),
([7, 8, 9, 10, 11, 12],),
]
# example two - update rows to individual values using executemany
s.execute(
A.__table__.update()
.where(A.id == bindparam("_id"))
.values(data=A.data + bindparam("values")),
[
{"_id": 1, "values": [13, 14, 15]},
{"_id": 2, "values": [16, 17, 18]},
{"_id": 3, "values": [19, 20, 21]},
],
)
assert list(s.query(A.data).order_by(A.id)) == [
([1, 2, 3, 10, 11, 12, 13, 14, 15],),
([4, 5, 6, 10, 11, 12, 16, 17, 18],),
([7, 8, 9, 10, 11, 12, 19, 20, 21],),
]