Python - 执行sqlite查询后的正则表达式模式匹配问题

时间:2014-09-11 22:49:13

标签: python mysql sql regex sqlite

我试图从一个表中提取一些信息,并使用Sqlite和Python将其存储在另一个表中。表1包含(www.abc.com)形式的网站列表。我试图从每一行中提取(abc)部分并将其存储在表2中,表2中还保留了每个站点的计数。如果该站点已经存在于表2中,那么它只是递增计数。

这里是我的代码:

p = re.compile('^.+\.([a-zA-Z]+)\..+$')
for row in c.execute('SELECT links FROM table1'):
    link = p.match(row[0])

    if link.group(1):
        print(link.group(1))
        c.execute('SELECT EXISTS(SELECT 1 FROM table2 WHERE site_name = ?)', (link.group(1), ))

当我运行脚本时,它只执行一次,然后我得到:

Traceback (most recent call last):
  File "test.py", line 43, in <module>
      link = p.match(row[0])
TypeError: expected string or buffer

如果我注释掉c.execute行,则会正确打印所有站点名称。我是Python和Sqlite的新手,所以我不确定是什么问题。

任何帮助都会很棒,提前谢谢。

2 个答案:

答案 0 :(得分:1)

问题在于您正在迭代其行包含单个字符串的游标:

for row in c.execute('SELECT links FROM table1'):

...但是,在迭代过程中,您将其更改为一个游标,其行包含一个数字:

    c.execute('SELECT EXISTS(SELECT 1 FROM table2 WHERE site_name = ?)', (link.group(1), ))

因此,当您获得下一行时,它将是[1]而不是['http://example.com'],因此p.match(row[0])将数字1传递给match ,它抱怨1不是字符串或缓冲区。


为了将来参考,通过查看中间值来调试事物非常有用。无论你是在调试器中运行,还是只是添加print(row)调用等来记录正在发生的事情,你都知道它第一次通过循环,但它第二次失败了,那{ {1}}失败时看起来像row。这样可以让您更容易找到问题(或者让您在SO上提出更好的问题,因为显然您仍然无法自己找到所有问题。)


你可以用(至少)三种方式解决这个问题,按照“善于适当”的顺序递增:

  • 从第一个查询中获取所有值,然后循环遍历这些值,这样您的第二个查询就不会妨碍。
  • 为每个查询使用单独的游标,而不是重复使用相同的游标。
  • 首先不要进行第二次查询 - 这是一个[1]查询,而你没有对这些行做任何事情,那么它有什么用呢?

答案 1 :(得分:0)

内部执行可能正在踩光标迭代器状态。尝试为该查询创建第二个游标对象。