2016-07-26 109 views
1

我正在使用pandas,sqlite和sqlalchemy搜索一串字符串以獲取子字符串。這個項目的靈感來自於this tutorial.Pandas + SQLite「無法使用索引」錯誤

首先,我創建了一個字符串列的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模塊明確地創建了索引,該模塊產生了「無法使用索引」錯誤。

因此,現在看來我已經創建了索引,但由於某種原因,我無法使用它。爲什麼會這樣?而且,如何使用pandas api創建索引,而不必使用sqlite3模塊?

+0

錯誤消息「無法使用索引」似乎與「pd.read_sql_query()」調用有關,而不是您直接使用sqlite3模塊創建索引的部分。 – bernie

+0

是的,它似乎是我成功創建索引,那爲什麼我無法使用它? – Malonge

+0

我認爲這與你使用LIKE'%[某個詞]%' – bernie

回答

1

錯誤消息「無法使用索引」似乎與pd.read_sql_query()調用有關,而不是直接使用sqlite3模塊創建索引的部分。

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