【问题标题】:Scrapy mysql pipeline critical section in runInteraction()runInteraction() 中的 Scrapy mysql 管道关键部分
【发布时间】:2012-07-11 02:22:36
【问题描述】:

我需要帮助修复我的管道抓取代码中的关键部分。

我在 scrapy 中使用这个 MySQL 管道(来自 http://snippets.scrapy.org/snippets/33/):

class SQLStorePipeline(object):

def __init__(self):
    self.dbpool = adbapi.ConnectionPool('MySQLdb', db='mydb',
            user='myuser', passwd='mypass', cursorclass=MySQLdb.cursors.DictCursor,
            charset='utf8', use_unicode=True)

def process_item(self, item, spider):
    # run db query in thread pool
    query = self.dbpool.runInteraction(self._conditional_insert, item)
    query.addErrback(self.handle_error)

    return item

def _conditional_insert(self, tx, item):
    # create record if doesn't exist. 
    # all this block run on it's own thread


    # START CRITICAL SECTION
    some_critical_code_here
    # STOP CRITICAL SECTION


    tx.execute("select * from websites where link = %s", (item['link'][0], ))
    result = tx.fetchone()
    if result:
        log.msg("Item already stored in db: %s" % item, level=log.DEBUG)
    else:
        tx.execute(\
            "insert into websites (link, created) "
            "values (%s, %s)",
            (item['link'][0],
             datetime.datetime.now())
        )
        log.msg("Item stored in db: %s" % item, level=log.DEBUG)

def handle_error(self, e):
    log.err(e)

一切正常。

如您所见,我已经知道代码中的关键部分在哪里。但是我对python真的很陌生并且不知道如何使用一些锁或类似的东西来防止多个线程进入关键部分。

你能帮帮我吗? 如果你能把进入和离开关键部分的代码发给我,我可以在这段代码中使用,那就太好了。

谢谢各位。

【问题讨论】:

    标签: python multithreading twisted scrapy mysql-python


    【解决方案1】:

    无论如何,我通过合并关键部分中的 sql 语句来解决它 感谢在 Scrapy IRC 上有 nick 牙病的家伙提出这个想法

    【讨论】:

      【解决方案2】:

      即使您使用的是 Twisted,通常所有涉及阻塞的事情都需要以不同的方式完成,但您处于 Twisted 的特定部分,其中阻塞是可以的。所以这应该像分配一个所有线程都能够引用的 Lock 对象一样简单,然后获取它:

      import threading
      
      insert_critical_lock = threading.Lock()
      
      ...
      
      def _conditional_insert(self, tx, item):
      
          with insert_critical_lock:
              # START CRITICAL SECTION
              some_critical_code_here
              # STOP CRITICAL SECTION
      
          tx.execute("select * from websites where link = %s", (item['link'][0], ))
          ...
      

      【讨论】:

        猜你喜欢
        • 2012-05-13
        • 2017-12-10
        • 2015-07-25
        • 1970-01-01
        • 1970-01-01
        • 2014-05-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多