2016-07-26 13 views
1

Ich benutze Pandas, SQLite und SQLechemy, um eine Reihe von Zeichenfolgen für Teilzeichenfolgen zu suchen. Dieses Projekt ist inspiriert von this tutorial.Pandas + SQLite Fehler "Kann Index nicht verwenden"

Zuerst erstelle ich eine SQLite-Datenbank mit einer Spalte von Strings. Dann iteriere ich durch eine separate Datei von Zeichenfolgen und suche nach diesen Zeichenfolgen in der Datenbank.

Ich habe festgestellt, dass der Prozess langsam ist, also habe ich einige Nachforschungen angestellt und festgestellt, dass ich einen Index für meine Spalte erstellen musste. Als ich die Anweisungen here in der sqlite Shell befolgte, schien alles gut zu funktionieren.

Wenn ich jedoch versuche, einen Index in meinem Python-Skript zu erstellen, erhalte ich den Fehler "kann Index nicht verwenden".

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 
     ) 

Man kann sehen, dass ich zum ersten Mal, indem die richtigen Keyword-Argumente an die to_sql Methode einen Index zu erstellen versucht. Als ich das alleine gemacht habe, habe ich einen Fehler bekommen, der besagt, dass der Index nicht gefunden werden konnte. Dann habe ich den Index explizit über das Modul sqlite3 erstellt, was den Fehler "Kann nicht Index verwenden" lieferte.

So jetzt scheint es, dass ich meinen Index gemacht habe, aber aus irgendeinem Grund kann ich es nicht verwenden. Warum sollte das sein? Und wie erstellt man mit Hilfe der Pandas API einen Index, anstatt das Modul sqlite3 verwenden zu müssen?

+0

Diese Fehlermeldung "kann Index nicht verwenden" scheint sich auf den Aufruf 'pd.read_sql_query()' zu beziehen und nicht den Teil, in dem Sie den Index direkt mithilfe des Moduls sqlite3 erstellen. – bernie

+0

Ja, es scheint, dass ich den Index erfolgreich erstellt habe, also warum kann ich ihn nicht verwenden? – Malonge

+0

Ich denke, es hat mit Ihrer Verwendung von LIKE '% [irgendein Begriff]%' – bernie

Antwort

1

Diese Fehlermeldung "kann den Index nicht verwenden" scheint sich auf den Aufruf pd.read_sql_query() zu beziehen und nicht den Teil, in dem Sie den Index direkt mit dem Modul sqlite3 erstellen.

Eine Abfrage mit some_col LIKE '%[some term]%' kann keinen Index für some_col verwenden. Abfragen mit some_col LIKE '[some_term]%' andererseits können einen Index auf some_col verwenden.