PyQt - Manejo de bases de datos

La API de PyQt contiene un elaborado sistema de clases para comunicarse con muchas bases de datos basadas en SQL. Su QSqlDatabase proporciona acceso a través de un objeto Connection. A continuación se muestra la lista de controladores SQL disponibles actualmente:

No Señor. Tipo de controlador y descripción
1

QDB2

IBM DB2

2

QIBASE

Controlador Borland InterBase

3

QMYSQL

Controlador MySQL

4

QOCI

Controlador de interfaz de llamada de Oracle

5

QODBC

Controlador ODBC (incluye Microsoft SQL Server)

6

QPSQL

Controlador PostgreSQL

7

QSQLITE

SQLite versión 3 o superior

8

QSQLITE2

SQLite versión 2

Ejemplo

Se establece una conexión con una base de datos SQLite utilizando el método estático:

db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('sports.db')

Otros métodos de la clase QSqlDatabase son los siguientes:

No Señor. Métodos y descripción
1

setDatabaseName()

Establece el nombre de la base de datos con la que se busca la conexión.

2

setHostName()

Establece el nombre del host en el que está instalada la base de datos.

3

setUserName()

Especifica el nombre de usuario para la conexión.

4

setPassword()

Establece la contraseña del objeto de conexión, si la hubiera

5

commit()

Confirma las transacciones y devuelve verdadero si tiene éxito

6

rollback()

Revierte la transacción de la base de datos

7

close()

Cierra la conexión

La clase QSqlQuery tiene la funcionalidad para ejecutar y manipular comandos SQL. Se pueden ejecutar consultas SQL de tipo DDL y DML. El método más importante de la clase es exec_ (), que toma como argumento una cadena que contiene una declaración SQL a ejecutar.

query = QtSql.QSqlQuery()
query.exec_("create table sportsmen(id int primary key, 
   " "firstname varchar(20), lastname varchar(20))")

El siguiente script crea una base de datos de SQLite sports.db con una tabla de deportista poblada con cinco registros.

from PyQt4 import QtSql, QtGui

def createDB():
   db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
   db.setDatabaseName('sports.db')
	
   if not db.open():
      QtGui.QMessageBox.critical(None, QtGui.qApp.tr("Cannot open database"),
         QtGui.qApp.tr("Unable to establish a database connection.\n"
            "This example needs SQLite support. Please read "
            "the Qt SQL driver documentation for information "
            "how to build it.\n\n" "Click Cancel to exit."),
         QtGui.QMessageBox.Cancel)
			
      return False
		
   query = QtSql.QSqlQuery()
	
   query.exec_("create table sportsmen(id int primary key, "
      "firstname varchar(20), lastname varchar(20))")
		
   query.exec_("insert into sportsmen values(101, 'Roger', 'Federer')")
   query.exec_("insert into sportsmen values(102, 'Christiano', 'Ronaldo')")
   query.exec_("insert into sportsmen values(103, 'Ussain', 'Bolt')")
   query.exec_("insert into sportsmen values(104, 'Sachin', 'Tendulkar')")
   query.exec_("insert into sportsmen values(105, 'Saina', 'Nehwal')")
   return True
	
if __name__ == '__main__':
   import sys
	
   app = QtGui.QApplication(sys.argv)
   createDB()

La clase QSqlTableModel en PyQt es una interfaz de alto nivel que proporciona un modelo de datos editables para leer y escribir registros en una sola tabla. Este modelo se utiliza para poblar un objeto QTableView. Presenta al usuario una vista desplazable y editable que se puede colocar en cualquier ventana de nivel superior.

Un objeto QTableModel se declara de la siguiente manera:

model = QtSql.QSqlTableModel()

Su estrategia de edición se puede establecer en cualquiera de los siguientes:

QSqlTableModel.OnFieldChange Todos los cambios se aplicarán inmediatamente.
QSqlTableModel.OnRowChange Los cambios se aplicarán cuando el usuario seleccione una fila diferente
QSqlTableModel.OnManualSubmit Todos los cambios se almacenarán en caché hasta que se llame a submitAll () o revertAll ()

Ejemplo

En el siguiente ejemplo, la tabla de deportistas se usa como modelo y la estrategia se establece como:

model.setTable('sportsmen') 
model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)

   model.select()

La clase QTableView es parte del marco Model / View en PyQt. El objeto QTableView se crea de la siguiente manera:

view = QtGui.QTableView()
view.setModel(model)
view.setWindowTitle(title)
return view

Este objeto QTableView y dos widgets QPushButton se agregan a la ventana de QDialog de nivel superior. La señal presionada () del botón agregar está conectada a addrow () que realiza insertRow () en la tabla del modelo.

button.clicked.connect(addrow)
def addrow():
   print model.rowCount()
   ret = model.insertRows(model.rowCount(), 1)
   print ret

La ranura asociada con el botón de eliminar ejecuta una función lambda que elimina una fila, que es seleccionada por el usuario.

btn1.clicked.connect(lambda: model.removeRow(view1.currentIndex().row()))

El código completo es el siguiente:

import sys
from PyQt4 import QtCore, QtGui, QtSql
import sportsconnection

def initializeModel(model):
   model.setTable('sportsmen')
   model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)
   model.select()
   model.setHeaderData(0, QtCore.Qt.Horizontal, "ID")
   model.setHeaderData(1, QtCore.Qt.Horizontal, "First name")
   model.setHeaderData(2, QtCore.Qt.Horizontal, "Last name")
	
def createView(title, model):
   view = QtGui.QTableView()
   view.setModel(model)
   view.setWindowTitle(title)
   return view
	
def addrow():
   print model.rowCount()
   ret = model.insertRows(model.rowCount(), 1)
   print ret
	
def findrow(i):
   delrow = i.row()
	
if __name__ == '__main__':

   app = QtGui.QApplication(sys.argv)
   db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
   db.setDatabaseName('sports.db')
   model = QtSql.QSqlTableModel()
   delrow = -1
   initializeModel(model)
	
   view1 = createView("Table Model (View 1)", model)
   view1.clicked.connect(findrow)
	
   dlg = QtGui.QDialog()
   layout = QtGui.QVBoxLayout()
   layout.addWidget(view1)
	
   button = QtGui.QPushButton("Add a row")
   button.clicked.connect(addrow)
   layout.addWidget(button)
	
   btn1 = QtGui.QPushButton("del a row")
   btn1.clicked.connect(lambda: model.removeRow(view1.currentIndex().row()))
   layout.addWidget(btn1)
	
   dlg.setLayout(layout)
   dlg.setWindowTitle("Database Demo")
   dlg.show()
   sys.exit(app.exec_())

El código anterior produce la siguiente salida: