2017-04-15 3 views
0

ユーザーが独自のクエリ文字列を使用してクエリを行う必要があるデータセットがあります。現在のソリューションは、クエリが実行される一時的なメモリ内sqliteデータベースを作成します。辞書のリストでユーザー定義のクエリを実行

データセットは「フラット」な辞書のリストです。つまり、ネストされたデータはありません。クエリ文字列はSQLである必要はありませんが、既存のクエリフレームワークを使用して定義するのは簡単です。

オーダー(昇順、降順、カスタム)とフィルタリングをサポートする必要があります。

この質問の目的は、この使用例で有効な様々なソリューションを得ることです。

import sqlite3 

items = [ 
    {'id': 1}, 
    {'id': 2, 'description': 'This is a description'}, 
    {'id': 3, 'comment': 'This is a comment'}, 
    {'id': 4, 'height': 1.78} 
] 

# Assemble temporary sqlite database 
conn = sqlite3.connect(':memory:') 
cur = conn.cursor() 

knownTypes = { "id": "real", "height": "real", "comment": "text" } 

allKeys = list(set().union(*(d.keys() for d in items))) 
allTypes = list(knownTypes.get(k, "text") for k in allKeys) 

createTable_query = "CREATE TABLE data ({});".format(", ".join(["{} {}".format(x[0], x[1]) for x in zip(allKeys, allTypes)])) 
cur.execute(createTable_query) 
conn.commit() 

qs = ["?" for i in range(len(allKeys))] 
insertRow_query = "INSERT INTO data VALUES ({});".format(", ".join(qs)) 

for p in items: 
    vals = list([p.get(k, None) for k in allKeys]) 
    cur.execute(insertRow_query, vals) 
conn.commit() 

# modify user query here 
theUserQuery = "SELECT * FROM data" 

# Get data from query 
data = [row for row in cur.execute(theUserQuery)] 
+0

あなたの質問は何ですか?何がうまくいかない?異種ソリューションをお探しの場合は、[CodeReview](http://codereview.stackexchange.com/) – Parfait

+0

をお試しください。上記のSugestion @ Parfaitのおかげで、上記はうまくいきますが、ホイールの再発明は嫌いです。私は 'query(dataset、SQLqueryString)'のようなものを探していて、ユーザーのSQLをリストのコンパイルに安全に変換できると思っています。 – timyha

答えて

0

YAQLは私が探しているものです。

SQLは実行しませんが、クエリ文字列を実行します。これは複雑なユーザー定義の並べ替えとフィルタリングを行う簡単な方法です。