Database programming with Python

I am trying to build a database application in Python using a form for data input. I am looking for a full example of database CRUD programming to get a better overall picture of what is required.

I have found many examples of data manipulation using Terminal input, but nothing using Forms input. I also understand how to do this programatically, but using a Form is a whole new ball game.

What I am asking for is a link to a good website where I can see practical examples of this type of programming, or a good book that will take me through the steps to do it.

I am a hobbyist trying to teach himself to program in Python with main interest in database access and manipulation. I am using Visual Studio on a Mac Mini M1. I have created the form and a database to which I can connect and create new records (all working fine), but nothing else.

Any help would be appreciated.
Neil

Using a form should be somewhat orthogonal to using the database. If you know how to read from the form, you get the same input you would have from the terminal, and use it the same way to interact with your database.

OK thanks Clint. I will persevere.

Could you expand a little on what you mean by using a form. Are you using a GUI framework like tkinter, or Qt?

If your using Qt RealPython have a great article walking through how to work with databases.

This tutorial takes you through making connections, making queries, inserting records, and also showing the data in a user interface.

If you provide a bit more information about what database your using, and what ui framework or better yet post code your more likely to get solid targeted help.

Hello Rob
Thanks for your response. Sorry my query was so woolly. The reason was that I didn’t want to waste anyone’s time before I had explored some better source material to learn from.
I am using Sqlite3 for the database and have tried several ways to get through the GUI bit to produce a user entry form and succeeded with help from this forum. I have tried Tkinter and also PyQt6, both of which are quite complicated due to (from my perspective) a lack of adequate detailed explanation with examples. I am good at learning from real life examples. I have actually created a form for an eBooks Library desktop app and have connected to the form using Sqlite3. I can now also create and save a new record. However, I have short circuited my learning so I am missing the whole schema of multiple forms or popups, viewing records, editing (all CRUD aspects) and I do want to use PyQt6 for ease of form building.
So, I guess what I am saying is that I am looking for a tutorial (or reference material) that will take me through all the aspects of creating a database app driven by Python forms using a GUI like PyQt6. Most examples that I have seen don’t have a form for input, take all their SQL actions through the actual program, are not user friendly and certainly have no input medium to allow for user input.
I know that my approach to this learning experience is rather abnormal, in that I am not going through the process of learning Python programming step by step first, then database programming after that. I am learning on a need-to-know basis looking for each aspect that I need to know and understanding what it does before using it. You see, I am 90 next month so time is a factor, am not interested in the millions of other uses for Python (only database programming) and am doing this to keep my brain alive apart from the great excitement that it brings to me.
Your article link above is exactly the type of thing that I am looking for, so thanks for that. I am going to study it after the weekend.
Best wishes
Neil

No worries Neil, we all tend to approach things in slightly different ways. Programmers tend to be fair detail oriented folks and its easier to hook out interest if you provide a little code.

I would try to think of Widgets (another common name for forms) as completely separate from the database side of things. They’re just a way of providing value editors to the user.

Id try to disconnect the UI and the rest of your code in your head. it’ll make things simpler.
Usually in Qt we have a View which lets the user edit the data, and a controller which handles the data when prompted.

heres a quick example.

import typing
from PyQt6 import QtWidgets, QtCore


class DataEntry(typing.NamedTuple):
    name: str
    age: int


class DataEntryWidget(QtWidgets.QWidget):
    # this is a signal. A signal is a special object that we can watch for changes by connecting to it.
    saveButtonClicked = QtCore.Signal(DataEntry)

    def __init__(self, parent=None):
        super().__init__(parent=parent)

        self.name_editor = QtWidgets.QLineEdit()
        self.age_editor = QtWidgets.QSpinBox()
        self.age_editor.setMinimum(0)
        self.age_editor.setMaximum(200)

        self.save_button = QtWidgets.QPushButton("Save")

        # a layout is a container that positions our widgets automatically for us.
        # a form layout adds optionally adds a label to each widget we add.
        layout = QtWidgets.QFormLayout()
        layout.addRow("Name", self.name_editor)
        layout.addRow("Age", self.age_editor)
        layout.addRow(self.save_button)

        self.setLayout(layout)

        # we connect onConnectButtonClicked to the save buttons clicked singal
        # this will cause onConnectButtonClicked to be called when the button
        # is clicked.
        self.save_button.clicked.connect(self.onConnectButtonClicked)

    def onConnectButtonClicked(self):
        """
        This function is called when the save button is clicked

        we use this function to gather the data from the ui and then broadcast it for
        other things to consume.
        """

        # for convenience, put our data into a class to make it easy to pass about.
        data = DataEntry(self.name_editor.text(), self.age_editor.value())

        # anything connected to this signal will receive the data.
        self.saveButtonClicked.emit(data)


class DataEntryController(QtCore.QObject):
    def __init__(self, parent=None):
        super().__init__(parent=parent)

    def onSaveButtonClicked(self, data: "DataEntry"):
        print("do something with the data", data)


if __name__ == "__main__":
    app = QtWidgets.QApplication()

    view = DataEntryWidget()
    controller = DataEntryController()
    
    # we connect the views saveButtonClicked signal to the controllers onSaveButtonClicked method so when the button gets clicked it is sent the uis state as a DataEntry object   
    view.saveButtonClicked.connect(controller.onSaveButtonClicked)
    view.show()
    app.exec()

Thank you Rob for your quick reply and taking the trouble to give me the example which I will study form tomorrow.
As a matter of interest, here is the only post I’ve had (with tremendous help) on this forum.

Sorry I can’t do much today but have family commitments.
I will reply soon.

Good morning Rob

I tried to run your program so that I couyld see the result as well as examine the coding that created it, but got two errors (using VS Code editor). The first I managed to correct, but maybe not correctly. It was here:
saveButtonClicked = QtCore.Signal(DataEntry) where Signal was not defined so I changed it to read:
QtCore.pyqtSignal(DataEntry) and it worked. Lucky try I guess.
The other one I have no idea how to correct. The error message re this line:
app = QtWidgets.QApplication() is:

Please help me to run this example as it looks very interesting and I need to know how it works. Thanks. In the meantime I am going over to the tutorial on real python that you sent the link for. First impression: very comprehensive tut. thanks.
Neil

Please share computer output the same as program text.

The type error already tells what it expects. A QApplication wants a list of strings as arguments. The simplest would be:

app = QtWidgets.QApplication([])

That would mean that at start up you can never pass any arguments in. To make that possible write

import sys
app = QtWidgets.QApplication(sys.argv)

The sys.argv holds a list of the arguments your Python program was started with, so you pass them to the QApplication.

1 Like

Thank you Menno. Sorry about the computer output display. I’m still learning how to do this type of thing for this forum and will get it right next time.

I made that change and the code worked as you expected. Thank you very much. I shall now examine the code to learn more from it.

No need to be. You have to see it once to realise it. In this case I wanted to copy/paste the part of the message I was referring to - makes it clearer. But because of the screenshot, I couldn’t.

Apologies Neil, I wasn’t able to check in yesterday. I’m glad @Mholscher got you sorted.

I use PySide6 not PyQt6 and PySide6 doesn’t require that argument. Sorry for the confusion I should have checked that code in PyQt6 before posting it.

No problem Rob. Your example was really an eye opener as was the tut at RealPython. Totally different to what I have been doing so a new learning experience for me. Really good stuff Rob. Thanks a ton.
Best wishes
Neil

I’m glad it helped. sometimes a nice simple example is worth allot.