SQLAlchemy 反射:如何更新反射表中的数据?

1 投票
1 回答
3176 浏览
提问于 2025-04-17 18:25

使用SQLAlchemy反射,我该如何插入或更新表中的数据呢?

我刚刚学会了如何使用SQLAlchemy反射来查询特定的表,具体内容可以参考这里。我已经完成了数据的处理,现在想把数据保存到数据库里,但我不知道该怎么做。以下是我目前尝试过的代码。

class Member(Base):
    __table__ = Table('member', Metadata, autoload=True)
    def set_password(self, member_id, password):
        data = None
        for data in session.add( self.__table__.c.member_id, self.__table__.c.parking_slot_id):            
            self.__table__.c.id = member_id
            self.__table__.c.password = password
            session.flush()   

但是这个方法失败了,错误信息是:

Traceback (most recent call last):
  File "/home/workspace/testmod/src/tester.py", line 44, in <module>
    m.set_password(m, 1, "password")
  File "/home/workspace/testmod/src/tester.py", line 36, in set_password
    for data in session.add(self.__table__.c.id, self.__table__.c.password):            
  File "/usr/local/lib/python3.2/dist-packages/SQLAlchemy-0.8.0b2-py3.2.egg/sqlalchemy/orm/session.py", line 1363, in add
    if _warn and self._warn_on_events:
  File "/usr/local/lib/python3.2/dist-packages/SQLAlchemy-0.8.0b2-py3.2.egg/sqlalchemy/sql/expression.py", line 1932, in __bool__
    raise TypeError("Boolean value of this clause is not defined")
TypeError: Boolean value of this clause is not defined 

那么,我们该如何在反射的表中更新或插入数据呢?

1 个回答

3

你现在使用 session.add() 的方式完全不对——它没有返回值,并且接受的是映射对象(比如一个 Member 实例:m = Member()),而不是列对象。你传的第二个参数是一个内部参数,公众不使用,所以你才会遇到错误。

我强烈建议你好好看看这个 教程,这样你就能理解 Session 和 add() 方法应该怎么用。

你想要的具体用法可能不是很明确,但你给 set_password() 的调用方式表明你想要根据给定的 member_id 修改某一行的密码。这意味着这应该是一个查找方法,应该在类级别上进行:

class Member(Base):
    __table__ = Table('member', Metadata, autoload=True)

    @classmethod
    def set_password(cls, member_id, password):
        member = session.query(Member).filter_by(member_id=member_id).one()
        member.password = password
        session.flush()

# usage:

Member.set_password(56, "somepassword")

如果你真的只是想更新那个值,而不再需要你刚加载的 Member 对象,可以更高效地使用直接的 update() 方法来完成:

class Member(Base):
    __table__ = Table('member', Metadata, autoload=True)

    @classmethod
    def set_password(cls, member_id, password):
        session.query(Member).filter_by(member_id=member_id).\
                    update({'password':password}, synchronize_session=False)

撰写回答