SQLAlchemy无法在更新值时设置属性错误

2024-06-17 12:54:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我在后端PostgreSQL数据库中有一个表mailtable,我使用SQLAlchemy ORM使用给定的mailId查询它。对于下面的代码,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。 我该怎么做?我相信这一定是一个非常简单的问题,但就我的一生而言,我看不出问题所在。在

非常感谢。在


Tags: helloworldbasebindsessionpostgresqlmtreflect
2条回答

通过调用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自动反映ORM类和表。下面是您可能要编写的代码:

^{pr2}$

您正在直接查询Table对象,而不是通过插入指令的模型:

mt = metaAm.tables['mailtable']
print(type(mt))
# <class 'sqlalchemy.sql.schema.Table'>

当您查询一个表时,会返回一个<class 'sqlalchemy.util._collections.result'>的实例,它是namedtuple的类型。元组是不可变的,因此不能更改其属性的值。在

相关问题 更多 >