我有一个包含大量文本数据的大表。下面的代码片段是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.
我读到这种分配给行的方式在sqlalchemy
0.9 或其他版本之前的版本中是可能的。(我有 1.2.0,但降级似乎是一个愚蠢的选择,因为必须有办法做到这一点。)
而且我知道这种基于查询结果分配给单行sqlsoup
的方式在sqlalchemy
.
我的问题:
我该怎么做row.processed_text = result
才能获得所需的单行更新?
由于这应该适用于不同的数据库,其中列的名称可能不同,我想避免硬编码,Query(data_table).where(data_table.primary_key == row.primary_key).update()
因为我不一定知道主键列的名称。
PS.: 数据库的性能不是这里的重点,因为我有时间,这只是很少运行computationally_heavy()
,反正消耗了很多时间。
另外我是社会科学家,不是程序员,很抱歉,如果这是一个非常愚蠢的问题......
好像你已经混合了Core和ORM。模型实例通过检测跟踪对属性的更改。Table
使用您的表,而不仅仅是定义一个声明类:
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,但降级似乎是一个愚蠢的选择,因为必须有办法做到这一点。)
结果元组可分配是由于一个问题,并在 1.0.5 版中修复。这并不意味着他们以与 ORM 相同的方式跟踪更改。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句