使用PySide将数据库列转换为Python列表?

时间:2017-10-04 13:44:33

标签: python qt pyside qsqltablemodel

使用PySide / Qt的QSqlTableModel有一种快速,优雅的方法将数据库列转换为Python列表吗?例如,在R中,这将是一行短代码。现在,我在Python中手动循环遍历行,这对于高级语言来说似乎很麻烦:

<!DOCTYPE html>
<html>
    <head>
        <script src="dist/vss-web-extension-sdk/lib/VSS.SDK.min.js"></script>
    </head>
    <body>
        <script type="text/javascript">
            VSS.init({
                explicitNotifyLoaded: true,
                usePlatformScripts: true,
                usePlatformStyles: true
            });

            VSS.ready(function () {
                require(["VSS/Controls", "VSS/Controls/Splitter"]);

                VSS.notifyLoadSucceeded();
            });
        </script>

        <div class="hub-view explorer">
            <div class="splitter horizontal stateful toggle-button-enabled">
                <script class="options" defer="defer" type="application/json">
                    {
                        "collapsedLabel": "Custom Explorer",
                        "settingPath": "Web/UIState/Custom/Splitter",
                        "initialSize": 217
                    }
                </script>

                <div class="leftPane">
                    <div class="left-hub-content">
                        Left Pane Content
                    </div>
                </div>
                <div class="handleBar">
                    <div class="handlebar-label" title="Custom Explorer">
                        <span class="handlebar-label-text">Custom Explorer</span>
                    </div>
                </div>
                <div class="rightPane">
                    <div class="hub-title">Content Placeholder</div>
                    <div class="right-hub-content">
                            Right Pane Content
                    </div>
                </div>
            </div>
        </div>
    </body>
</html>

2 个答案:

答案 0 :(得分:1)

无需创建模型来获取一组值。使用查询获取值更简单,更有效。这不会给你一个单行 - 但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&#39; s cursor.fetchall中的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())])

答案 1 :(得分:1)

对于C ++中的所有Qt方法,PySide层几乎是1比1。下面给出了一些C ++代码。

因为Qt Sql层是针对后端数据库类型抽象的,并且在事件循环上面向Gui接口,所以它没有R或其他语言可用的相同的一个衬里。虽然你可以在几行内完成。

此外,Qt的SQL错误处理方法通常是查询上一个错误或查看execopen调用的返回值。元组在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如何处理它的SQL调用的所有内容......它仍然与其他Python库与数据库进行交互:

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

希望有所帮助。