Issue
Using PySide/Qt's QSqlTableModel is there a quick, elegant way to turn a database column into a Python list? In R, for example, this would be one, short line of code. Right now, I'm manually looping over rows in Python, which seems cumbersome for a high level language:
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
Solution
There is no need to create a model just to get a set of values. It is much simpler and more efficient to use a query to get the values. This won't give you a one-liner - but one of the main strengths of Python is its readability, not its brevity.
The example below could easily be adapted to create a generic function that took a query-string and returned a list (or iterator) of values:
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:
Here is a generic fetchall
function (akin to cursor.fetchall in the python's sqlite3 module). My implementation of this takes either a query string or an active QSqlQuery
object, and returns either a list of values (for one column) or a tuple of values (for multiple columns):
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'))
This could also be implemented as a generator, which would be more suitable for very large result sets.
EDIT2:
If you use a model for querying then, once the rows have been selected, you can use a list comprehension to pull out the column values:
model = QSqlTableModel()
model.setTable('colors')
model.select()
# one liner ...
print([model.index(i, 1).data() for i in range(model.rowCount())])
Answered By - ekhumoro
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.