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

时间:2018-11-27 01:51:43

标签: python postgresql sqlalchemy

我在后端PostgreSQL数据库中有一个表mailtable,并且正在使用给定的mailId使用SQLAlchemy ORM查询该表。对于以下代码,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。 我怎样才能做到这一点?我敢肯定这肯定是一个非常简单的问题,但是我一生都看不到这个问题。

非常感谢。

2 个答案:

答案 0 :(得分:4)

通过调用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()

答案 1 :(得分:1)

您正在直接查询{"id":2,"name":"asd","description":"asd","image":"W29iamVjdCBBcnJheUJ1ZmZlcl0="} 对象,而不是通过检测模型进行查询:

Table

查询表时,将返回mt = metaAm.tables['mailtable'] print(type(mt)) # <class 'sqlalchemy.sql.schema.Table'> 的实例,它是<class 'sqlalchemy.util._collections.result'>的类型。元组是不可变的,因此您不能更改其属性的值。