Pandas + SQLite"不能使用索引"错误

时间:2016-07-26 00:50:17

标签: python pandas sqlite

我正在使用pandas,sqlite和sqlalchemy来搜索一串字符串以寻找子字符串。该项目的灵感来自this tutorial.

首先,我创建一个带有一列字符串的sqlite数据库。然后我遍历一个单独的字符串文件,并在数据库中搜索这些字符串。

我发现这个过程很慢,所以我做了一些研究,发现我需要在我的专栏上建立一个索引。当我按照sqlite shell中提供的here指令进行操作时,一切似乎都运行正常。

然而,当我尝试在我的python脚本中创建一个索引时,我得到了"不能使用索引"错误。

import pandas as pd
from sqlalchemy import create_engine # database connection
import datetime as dt



def load_kmer_db(disk_engine, chunk_size, encoding='utf-8'):
    start = dt.datetime.now()
    j = 0
    index_start = 1
    for df in pd.read_csv('fake.kmers.csv', chunksize=chunk_size, iterator=True, encoding=encoding):
        df.index += index_start
        j += 1
        df.to_sql('data', disk_engine.raw_connection(), if_exists='append', index=True, index_label='kmer_index')
        index_start = df.index[-1] + 1


def search_db_for_subsequence(disk_engine, sequence):
    """

    :param disk_engine: Disk engine for database containing query sequences
    :param sequence: Sequence for finding subsequences in the database
    :return: A data frame with the subsequences of sequence
    """
return pd.read_sql_query("SELECT kmer FROM data INDEXED BY kmer_index WHERE '" + sequence + "' LIKE '%' || kmer || '%'", disk_engine)

if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument('kmers', type=str, metavar='<kmer_file.txt>', help='text file with kmers')
    parser.add_argument('reads', type=str, metavar='<reads.fastq>', help='Reads to filter by input kmers')

    # Get the command line arguments.
    args = parser.parse_args()
    kmer_file = args.kmers
    reads_file = args.reads

    # Initialize database with filename 311_8M.db
    disk_engine = create_engine('sqlite:///311_8M.db') # This requires ipython to be installed

    load_kmer_db(disk_engine, 200)

    #****** Try explicitly calling the create index command
    #****** using the sqlite module.
    import sqlite3
    conn = sqlite3.connect('311_8M.db')
    c = conn.cursor()
    c.execute("CREATE INDEX kmer_index ON data(kmer);")

    reads = SeqReader(reads_file)
    for read in reads.parse_fastq():
        count += 1
        sequence = read[1]
        df = search_db_for_subsequence(
            disk_engine,
            sequence
        )

我可以看到我首先尝试通过将适当的关键字参数传递给to_sql方法来创建索引。当我单独这样做时,我得到一个错误,指出无法找到索引。然后我通过sqlite3模块明确地制作了索引,它产生了&#34;不能使用索引&#34;错误。

所以现在看来​​我已经制作了索引,但出于某种原因,我无法使用它。那为什么会这样?如何使用pandas api创建索引而不必使用sqlite3模块?

1 个答案:

答案 0 :(得分:1)

该错误消息&#34;无法使用索引&#34;似乎与pd.read_sql_query()调用有关,而不是直接使用sqlite3模块创建索引的部分。

some_col LIKE '%[some term]%'的查询无法使用some_col上的索引。另一方面,some_col LIKE '[some_term]%'的查询可以使用some_col上的索引。