sqlalchemy通过resultproxy-object更新值

时间:2018-04-06 15:03:19

标签: python sqlite sqlalchemy

我有一张包含大量文字数据的大表。下面的代码片段是我正在撰写的较大textcorpus-reader的最小示例。

from sqlalchemy import create_engine, MetaData, Table
from sqlalchemy.orm import sessionmaker

engine = create_engine("sqlite:///corpus.db")
meta = MetaData(bind=engine)
Session = sessionmaker(bind=engine, autoflush=False, expire_on_commit=False, autocommit=False)

data_table = Table("data", meta, autoload=True, autoload_with=engine)


def computationally_heavy(raw_text):
    """
    This does a lot of text-processing and needs a lot of RAM and CPU.
    For the sake of this example it does just this:
    """
    return raw_text.split("\n")


session = Session()
query = session.query(data_table).yield_every(10)

for i, row in enumerate(query):
    result = computationally_heavy(row.raw_text)

    # This is, what is not working - column 'processed_text' does already exist:
    row.processed_text = result

    if i % 250 == 0:
        s.flush()

session.commit()
session.close()

我的问题是我想更新for循环中的单行,但我得到:

AttributeError: can't set attribute. 

我读到在0.9之前的sqlalchemy版本中可以使用这种分配行的方式。 (我有1.2.0,但降级似乎是一个愚蠢的选择,因为必须有一种方法来做到这一点。)

我知道这种基于查询结果分配给单行的方式可以在sqlsoup中使用,但宁愿不使用另一个包,因为肯定有办法从sqlalchemy执行此操作。

我的问题:

我如何执行row.processed_text = result以获得所需的单行更新?

由于这应该适用于不同的数据库,其中列的名称可能不同,我希望避免使用硬编码的Query(data_table).where(data_table.primary_key == row.primary_key).update(),因为我不一定知道主键列的名称。

PS:数据库的性能不是这里的重点,因为我有时间,这应该很少运行,computationally_heavy()无论如何都要消耗很多时间。

我也是社会科学家,而不是程序员,很抱歉,如果这是一个非常愚蠢的问题......

1 个答案:

答案 0 :(得分:1)

好像你混合了CoreORM。模型实例通过instrumentation跟踪属性的更改。而不只是Table定义一个Declarative类,使用你的表:

from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base(metadata=meta)

class DataTable(Base):
    __table__ = Table("data", meta, autoload=True, autoload_with=engine)

在查询中使用它,生成的模型对象将跟踪其属性的更改:

query = session.query(DataTable).yield_every(10)
  

我读到这种分配行的方式可以在0.9之前的sqlalchemy版本中使用。 (我有1.2.0,但降级似乎是一个愚蠢的选择,因为必须有一种方法来做到这一点。)

结果元组可分配的原因是issuewas fixed in version 1.0.5。这并不意味着他们以与ORM相同的方式跟踪变化。