我在后端 PostgreSQL 数据库中有一个表 mailtable
,我正在使用给定的 mailId
使用 SQLAlchemy ORM 查询它。对于以下代码,amEngine
已设置。当它到达 mailRow.usercomment = 'Hello World'
行时,它抛出:
AttributeError: can't set attribute
Base = declarative_base()
Base.metadata.reflect(amEngine)
metaAm = MetaData()
metaAm.reflect(bind=amEngine)
mt = metaAm.tables['mailtable']
Session = sessionmaker(bind=amEngine)
amSession = Session()
mailRow = amSession.query(
mt
).filter(
mt.c.id == mailId
).first()
mailAddress = mailRow.address
mailRow.usercomment = 'Hello World'
amSession.flush()
amSession.commit()
我需要读取 address
列(成功)并更新 usercomment
列(抛出异常)。两列的 PostgreSQL 类型都是 text
。
我怎样才能做到这一点?我敢肯定这一定是一个非常简单的问题,但就我的生活而言,我看不到问题所在。
非常感谢。
最佳答案
通过调用 MetaData.reflect
,您要求 SQLAlchemy 自动检测 Table
对象,描述您的数据库。您可以使用这些对象来创建与语言无关的 SQL 查询,例如
engine.execute(update(mt).where(mt.c.id==1).values(usercomment='Hello World'))
但是,您还不能使用 Table
对象来执行正确的 ORM。当您查询一个 Table
对象(通过 session.query(mt)
)时,您将得到返回给您的只读结果 namedtuple
-像物体。设置它们的属性没有意义,因此您会观察到异常。
要享受真正的 ORM,您需要创建相应的 ORM 类并将它们映射到 Table
对象。
当然,您可以要求 SQLAlchemy 使用 automap 为您自动反射(reflect) ORM 类和表。 .这是您可能想要编写的代码:
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import sessionmaker
# Ask SQLAlchemy to reflect the tables and
# create the corresponding ORM classes:
Base = automap_base()
Base.prepare(amEngine, reflect=True)
# This is the ORM class we are interested in:
MailTable = Base.classes.mailtable
# Create the session, query, update and commit:
Session = sessionmaker(bind=amEngine)
session = Session()
mailRow = session.query(MailTable).get(mailId)
mailAddress = mailRow.address
mailRow.usercomment = 'Hello World'
session.commit()
关于python - SQLAlchemy 更新值时无法设置属性错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53491635/