sqlachemy查询作为迭代器的结果

时间:2015-11-10 20:24:43

标签: python iterator sqlalchemy gensim

我正在努力从sqlalchemy的查询中创建一个迭代器。

这是我到目前为止所尝试的内容

创建表格

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'}
          ])

我在迭代器上读到了我能做到的一切,但是没有得到它。 这里我创建的类来获取迭代器但它不起作用 (虽然我指定休息时它会溢出)

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')

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

   import gensim
   gensim.models.Word2Vec(x1)

提前致谢

2 个答案:

答案 0 :(得分:1)

您的支票if not self.xResultCollection将始终返回False,因为结果对象的truth value始终为True

next方法中,你有一个for和while循环,这不应该是真正需要的,next方法应该只返回一个元素,那里不需要循环。< / p>

由于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()

答案 1 :(得分:0)

对于那些对使用gensim感兴趣的人。

事实证明,问题是gensim需要一个迭代器,我们可以在其上返回(迭代查询游标的结果,消耗它)。

参见讨论here

这似乎对我有用

trace()

这里的词汇

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)

我在一个带有100万条目(科学论文标题)的postgresql上运行,大约90秒没有问题 我希望这能帮助别人