2016-09-09 32 views
6

Utworzono bazę danych sqlite przy użyciu pandy df.to_sql, jednak uzyskanie dostępu do niej wydaje się znacznie wolniejsze niż czytanie w pliku CSV o pojemności 500 MB.jak ustawić klucz podstawowy podczas zapisu pandasowej ramki danych do tabeli bazy danych sqlite za pomocą df.to_sql

muszę:

  1. ustawić klucz podstawowy dla każdej tabeli stosując metodę df.to_sql
  2. powiedzieć bazy sqlite co typ danych każdej z kolumn w moim 3.dataframe jesteś? - Mogę przekazać listę takich jak [Integer Integer tekstu, tekst]

kodu .... (przycisk Format kod nie działa)

if ext == ".csv": 
df = pd.read_csv("/Users/data/" +filename) 
columns = df.columns columns = [i.replace(' ', '_') for i in columns] 

df.columns = columns 
df.to_sql(name,con,flavor='sqlite',schema=None,if_exists='replace',index=True,index_label=None, chunksize=None, dtype=None) 

Odpowiedz

5

Niestety nie ma sposobu, aby ustawić teraz klucz podstawowy w metodzie pandas df.to_sql(). Dodatkowo, aby sprawić, by było więcej bólu, nie można ustawić klucza podstawowego w kolumnie w sqlite po utworzeniu tabeli.

Jednak obecnie praca polega na utworzeniu tabeli w sqlite za pomocą metody pandas df.to_sql(). Następnie możesz utworzyć zduplikowaną tabelę i ustawić klucz podstawowy, a następnie skopiować dane. Następnie upuść stary stół, aby posprzątać.

To byłoby coś na kształt tego.

import pandas as pd 
import sqlite3 

df = pd.read_csv("/Users/data/" +filename) 
columns = df.columns columns = [i.replace(' ', '_') for i in columns] 

#write the pandas dataframe to a sqlite table 
df.columns = columns 
df.to_sql(name,con,flavor='sqlite',schema=None,if_exists='replace',index=True,index_label=None, chunksize=None, dtype=None) 

#connect to the database 
conn = sqlite3.connect('database') 
c = conn.curser() 

c.executescript(''' 
    PRAGMA foreign_keys=off; 

    BEGIN TRANSACTION; 
    ALTER TABLE table RENAME TO old_table; 

    /*create a new table with the same column names and types while 
    defining a primary key for the desired column*/ 
    CREATE TABLE new_table (col_1 TEXT PRIMARY KEY NOT NULL, 
          col_2 TEXT); 

    INSERT INTO new_table SELECT * FROM old_table; 

    DROP TABLE old_table; 
    COMMIT TRANSACTION; 

    PRAGMA foreign_keys=on;''') 

#close out the connection 
c.close() 
conn.close() 

W przeszłości zrobiłem to, ponieważ stanąłem przed tym problemem. Po prostu zapakowałem całość, aby było wygodniejsze ...

W moim ograniczonym doświadczeniu z sqlite stwierdziłem, że nie mogę dodać klucza podstawowego po utworzeniu tabeli, co uniemożliwiło wykonanie Zaktualizuj wstawki lub UPSERTS, a UPDATE JOIN spowodowało wiele frustracji i niekonwencjonalnych obejść.

Wreszcie, w metodzie pandas df.to_sql() znajduje się argument słowa kluczowego dtype, który może przyjmować słownik nazw kolumn: typy. IE: dtype = {col_1: TEXT}

2

W oparciu o odpowiedź Chrisa Guarino, oto kilka funkcji, które zapewniają bardziej ogólne rozwiązanie. Zobacz przykład na dole, aby dowiedzieć się, jak z nich korzystać.

import re 

def get_create_table_string(tablename, connection): 
    sql = """ 
    select * from sqlite_master where name = "{}" and type = "table" 
    """.format(tablename) 
    result = connection.execute(sql) 

    create_table_string = result.fetchmany()[0][4] 
    return create_table_string 

def add_pk_to_create_table_string(create_table_string, colname): 
    regex = "(\n.+{}[^,]+)(,)".format(colname) 
    return re.sub(regex, "\\1 PRIMARY KEY,", create_table_string, count=1) 

def add_pk_to_sqlite_table(tablename, index_column, connection): 
    cts = get_create_table_string(tablename, connection) 
    cts = add_pk_to_create_table_string(cts, index_column) 
    template = """ 
    BEGIN TRANSACTION; 
     ALTER TABLE {tablename} RENAME TO {tablename}_old_; 

     {cts}; 

     INSERT INTO {tablename} SELECT * FROM {tablename}_old_; 

     DROP TABLE {tablename}_old_; 

    COMMIT TRANSACTION; 
    """ 

    create_and_drop_sql = template.format(tablename = tablename, cts = cts) 
    connection.executescript(create_and_drop_sql) 

# Example: 

# import pandas as pd 
# import sqlite3 

# df = pd.DataFrame({"a": [1,2,3], "b": [2,3,4]}) 
# con = sqlite3.connect("deleteme.db") 
# df.to_sql("df", con, if_exists="replace") 

# add_pk_to_sqlite_table("df", "index", con) 
# r = con.execute("select sql from sqlite_master where name = 'df' and type = 'table'") 
# print(r.fetchone()[0]) 

Jest Istotą tego kodu here