首页 > 解决方案 > 更新值时 SQLAlchemy 无法设置属性错误

问题描述

我在后端 PostgreSQL 数据库中有一个表mailtable,我使用 SQLAlchemy ORM 使用给定的mailId. 对于以下代码,amEngine已经设置好了。当它到达这mailRow.usercomment = 'Hello World'条线时,它会抛出:

AttributeError:无法设置属性

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. 我怎样才能做到这一点?我确信这一定是一个非常简单的问题,但对于我的生活,我看不到这个问题。

非常感谢。

标签: pythonpostgresqlsqlalchemy

解决方案


通过调用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 类以及表。这是您可能想要编写的代码:

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()

推荐阅读