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: