我在后端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
。
我怎样才能做到这一点?我敢肯定这肯定是一个非常简单的问题,但是我一生都看不到这个问题。
非常感谢。
答案 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'>
的类型。元组是不可变的,因此您不能更改其属性的值。