2016-09-09 35 views
6

pandas df.to_sqlを使用してsqliteデータベースを作成しましたが、アクセスは500mb csvファイルの読み込みよりもかなり遅いようです。df.to_sqlを使用してpandasデータフレームをsqliteデータベーステーブルに書き込むときにプライマリキーを設定する方法

  1. がdf.to_sql方法
  2. を使用して各テーブルの主キーは私の 3.dataframeの列のそれぞれが何であるかをデータ型のsqliteデータベースを教えて設定します。

    私がする必要がありますか? - 私は[整数、整数、テキスト、テキスト]

コード....

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) 

答えて

5

は、残念ながら今のところ設定する方法はありません(フォーマットコードボタンが機能していない)のようなリストを渡すことができますpandas df.to_sql()メソッドの主キー。さらに、厄介なことを起こさせるために、テーブルが作成された後にsqliteの列に主キーを設定する方法はありません。

しかし、現時点での回避策は、pandas df.to_sql()メソッドを使用してsqliteでテーブルを作成することです。次に、重複したテーブルを作成し、プライマリキーを設定してデータをコピーします。次に古いテーブルを落としてきれいにしてください。

これは、この行に沿ったものです。

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() 

これまで私はこの問題に直面していました。ちょうどそれをより便利にするための関数としてすべてをラップしました...

私の限られた経験でsqlite私は、テーブルが作成された後、実行することができない主キーを追加することができないことがわかった更新インサートまたはUPSERTS、およびUPDATE JOINは、多くの不満と慣習的でない回避策を引き起こしました。

最後に、pandas df.to_sql()メソッドには、dtypeキーワード引数があります。これは、列名の型の辞書を取ります。 IE:dtype = {col_1:TEXT}

2

Chris Guarinoの回答を基に、より一般的な解決策を提供する関数を次に示します。それらの使用方法については、下の例を参照してください。

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]) 

は、このコードの主旨ありhere

関連する問題