2017-10-04 9 views
1

PySide/QtのQSqlTableModelを使用すると、データベース列をPythonリストにすることができます。 Rでは、例えば、これは短いコード行です。今、私は手動で、高レベルの言語のための面倒思われる、Pythonで行をループしています:PySideを使ってデータベース列をPythonリストに変換しますか?

def get_value_idx(value): 
    model = QSqlTableModel() 
    model.setTable("pvalues") 
    model.setFilter("val = '%s'" % (value)) 
    model.select() 
    count = model.rowCount() 
    if count >= 1: 
     l = list() 
     for n in range(count): 
      id = model.record(n).value('id') 
      l.append(id) 
     return l # return id list 
    if count == 0: 
     return -1 # return id that shows error 

答えて

1

だけで、一連の値を取得するためのモデルを作成する必要はありません。クエリを使用して値を取得する方がはるかに簡単で効率的です。これはあなたに1ライナーを与えるものではありませんが、Pythonの主な強みの1つは、その簡潔さではなく読みやすさです。以下の例は、簡単な値のクエリ文字列を取り、リスト(またはイテレータを)返された汎用的な関数を作成するために適合させることができる

from PySide.QtSql import * 

db = QSqlDatabase.addDatabase('QSQLITE') 
db.setDatabaseName(':memory:') 
db.open() 
db.transaction() 
db.exec_('CREATE TABLE colors (id INTEGER PRIMARY KEY, color TEXT NOT NULL)') 
db.exec_("INSERT INTO colors VALUES(1, 'Red')") 
db.exec_("INSERT INTO colors VALUES(2, 'Blue')") 
db.exec_("INSERT INTO colors VALUES(3, 'Green')") 
db.exec_("INSERT INTO colors VALUES(4, 'Yellow')") 
db.commit() 

def list_colors(): 
    colors = [] 
    query = QSqlQuery('SELECT color FROM colors') 
    while query.next(): 
     colors.append(query.value(0)) 
    return colors 

print(list_colors())  

# or use a generator function: 

def generate_colors(): 
    query = QSqlQuery('SELECT color FROM colors') 
    while query.next(): 
     yield query.value(0) 

print(list(generate_colors())) 

EDIT

ここれます一般的なfetchall関数(cursor.fetchallのpythonのsqlite3 moduleに似ています)。この私の実装では、クエリ文字列またはアクティブQSqlQueryオブジェクトのいずれかをとり、戻りのいずれか(一方の列の)値のリストまたは(複数列の)値のタプル:

def fetchall(query): 
    if isinstance(query, str): 
     query = QSqlQuery(query) 
    result = [] 
    count = query.record().count() 
    indexes = range(count) 
    while query.next(): 
     if count == 1: 
      result.append(query.value(0)) 
     else: 
      result.append(tuple(query.value(i) for i in indexes)) 
    return result 

# one liner ... 

print(fetchall('SELECT color FROM colors')) 

これも実現することができます非常に大きな結果セットに適しているジェネレータとして使用できます。

EDIT2

model = QSqlTableModel() 
model.setTable('colors') 
model.select() 

# one liner ... 

print([model.index(i, 1).data() for i in range(model.rowCount())]) 
+0

ありがとうございます。モデルはGUI要素に結合されている場合にのみ使用されますか? – davideps

+0

@davideps。いいえ。しかし、クエリのように軽量ではないので、関数を呼び出すたびに作成するのは非効率です。モデルをクエリに使うつもりなら、QSqlTableModelをサブクラス化し、いくつかのメソッドを追加します(私の答えに追加した汎用のfetchallのように)。 – ekhumoro

+0

@davideps。私は、クエリにモデルを使用する例と列の値を引き出すためのリストの理解を追加しました。この特定の猫をスキンする方法はおそらく数十種類あります。 – ekhumoro

1

PySide:あなたが行が選択されていたら、その後、照会のためのモデルを使用している場合

は、あなたが列の値を引き出すために、リストの内包表記を使用することができますレイヤーはC++のすべてのQtメソッドでほぼ1対1です。いくつかのC++コードを以下に示します。

Qt Sqlレイヤは、バックエンドデータベースタイプ用に抽象化され、イベントループでGuiインターフェイスに対応しているため、Rや他の言語で使用できるものと同じライナーはありません。あなたはいくつかの行でそれを行うことができますが。

また、SQLのQtのエラー処理方法は、通常、最後のエラーを照会するか、execまたはopen呼び出しの戻り値を調べることです。タプルはC++ではネイティブではないため、Pythonインターフェイスではタプルがあまり使われません。

http://doc.qt.io/qt-4.8/sql-sqlstatements.html

http://doc.qt.io/qt-4.8/qsqltablemodel.html#details

QSqlTableModel model; 
model.setTable("employee"); 
model.setFilter("salary > 50000"); 
model.setSort(2, Qt::DescendingOrder); 
model.select(); 

for (int i = 0; i < model.rowCount(); ++i) { 
    QString name = model.record(i).value("name").toString(); 
    int salary = model.record(i).value("salary").toInt(); 
    qDebug() << name << salary; 
} 
クエリを指定

代替構文

QSqlQueryModel model; 
model.setQuery("SELECT * FROM employee"); 
int salary = model.record(4).value("salary").toInt(); 

http://doc.qt.io/qt-4.8/qsqlresult.html#size

QSqlQuery query("SELECT country FROM artist"); 
while (query.next()) { 
    QString country = query.value(0).toString(); 
    doSomething(country); 
} 

QtのSqlインターフェイスの真のパワーは、あなたが考えることができるほぼあらゆる種類の構成とデータベースエンジンから抽象化される方法でデータベースを表現するためのGUIの作成がいかに簡単であるかです。でも、Qtは、それをどのように処理するかについて言ったことすべてと

は、それはまだデータベースと対話するための他のPythonライブラリと同等のです... SQL呼び出しです:助け

How to retrieve SQL result column value using column name in Python?

cursor = conn.cursor(MySQLdb.cursors.DictCursor) 
cursor.execute("SELECT name, category FROM animal") 
result_set = cursor.fetchall() 
for row in result_set: 
    print "%s, %s" % (row["name"], row["category"]) 

希望。

+0

query.next()を使用した例が役に立ちます。ありがとうございました。 – davideps

関連する問題