有沒有必要建立一個模型,只是爲了獲得一組值。使用查詢來獲取值要簡單得多,效率更高。這不會給你一條線 - 但Python的主要優點之一是它的可讀性,而不是簡潔性。
下面的例子可以很容易地適應創建了一個查詢字符串的通用功能和返回值的列表(或迭代器):
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()))
編輯:
這裏一個通用的fetchall
函數(類似於python的sqlite3 module中的cursor.fetchall)。我的這種實現它可以是一個查詢字符串或主動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())])
謝謝。只有綁定到GUI元素時才使用模型? – davideps
@davideps。不,但它不像查詢那麼輕,所以每次調用函數時創建一個似乎效率低下。如果我打算使用模型進行查詢,我會繼承'QSqlTableModel'並添加一些方法(比如添加到我的答案中的通用'fetchall')。 – ekhumoro
@davideps。我添加了一個使用模型進行查詢的例子,以及列表理解來提取列值。有可能有很多方法來剝皮這個特殊的貓... – ekhumoro