sqlalchemy 查询的结果作为迭代器

results from an sqlachemy query as iterator

我正在努力根据 sqlalchemy 的查询创建迭代器。

这是我到目前为止尝试过的

创建 table

from sqlalchemy import create_engine, Column, MetaData, Table , Integer, String
engine = create_engine('sqlite:///test90.db')
conn = engine.connect()
metadata = MetaData()
myTable = Table('myTable', metadata,
     Column('Doc_id', Integer, primary_key=True),
     Column('Doc_Text', String))
metadata.create_all(engine)

conn.execute(myTable.insert(), [{'Doc_id': 1, 'Doc_Text' : 'first sentence'},
          {'Doc_id': 2, 'Doc_Text' : 'second sentence'},
          {'Doc_id': 3, 'Doc_Text' : 'third sentence'},
          {'Doc_id': 4, 'Doc_Text' : 'fourth sentence'}
          ])

我阅读了有关迭代器的所有内容,但不明白。 这里我创建的 class 是为了得到一个迭代器,但它不起作用 (尽管我指定了一个中断,它还是溢出了)

from sqlalchemy import create_engine

class RecordsIterator:
def __init__(self, xDB, xSQL):
    self.engine = create_engine(xDB)
    self.conn = self.engine.connect()
    self.xResultCollection = self.conn.execute(xSQL)
def __iter__(self):
    return self 
def next (self):
    while self.xResultCollection.closed is False:
        xText = (self.xResultCollection.fetchone())[1]
        xText = xText.encode('utf-8')
        yield xText.split()
        if not self.xResultCollection:
            break


x1 = RecordsIterator(xDB = 'sqlite:///test91.db', xSQL = 'select * from myTable')

如果您想知道为什么我不只是使用 generator 。 我需要在 gensim.Word2Vec 中提供迭代器,不幸的是,它不需要生成器

   import gensim
   gensim.models.Word2Vec(x1)

提前致谢

您的检查 if not self.xResultCollection 将始终 return False,因为结果对象的 truth value 将始终是 True.

在你的 next 方法中你有一个 for 和 while 循环,实际上不需要,next 方法应该只是 return 一个元素,没有必要在那里循环。

由于 self.xResultCollection 本身就是一个可迭代对象,您可以这样做:

class RecordsIterator:  
    def __init__(self, xDB, xSQL):
        self.engine = create_engine(xDB)
        self.conn = self.engine.connect()
        self.resultIterator = iter(self.conn.execute(xSQL))
    def __iter__(self):
        return self 
    def next (self):
        return next(self.resultIterator)[1].encode('utf-8').split()

对于那些有兴趣将其与 gensim 一起使用的人。

事实证明,问题在于 gensim 需要一个迭代器,我们可以在其上 return(迭代查询游标的结果,使用它)。

查看讨论 here

这似乎对我有用

import gensim 
from sqlalchemy import create_engine


xDB = 'sqlite:///test91.db'
xSQL = 'select * from myTable'
engine = create_engine(xDB)
conn = engine.connect()
xResultIterator = conn.execute(xSQL)


class MyIterator(object):
def __init__(self, xResults, xNrCol):
    self.xResults = xResults
    self.xNrCol = xNrCol
def __iter__(self):
    for xRecord in self.xResults:
        xText = (xRecord[self.xNrCol]).lower().encode('utf8')
        xToken = xText.split()
        if not xToken:
            continue
        yield xToken
    self.xResults = conn.execute(xSQL)  ### THIS SEEMS TO FIX IT 


#to use             

q1 = MyIterator(xResultIterator, xNrCol = 1)
model = gensim.models.Word2Vec(sentences = q1 , min_count = 1)

这里是词汇表

model.vocab.keys()

我 运行 在一个拥有 100 万个条目(科学论文标题)的 postgresql 上,在大约 90 秒内没有问题 我希望这会对其他人有所帮助