Форум программистов, компьютерный форум, киберфорум
Python: GUI, графика
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 28.06.2021
Сообщений: 17
PyQt5

Ошибка сегментации при работе с QtSql и Sqlite

10.12.2023, 18:21. Показов 1519. Ответов 16

Студворк — интернет-сервис помощи студентам
Добрый день.
Сталкиваюсь с проблемой при работе с Sqlite3 посредством QtSql. После удаления нескольких строк из базы далее во время штатного завершения работы программы окно закрывается, затем пауза в секунду - полторы, а затем вываливается ошибка:
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
При этом внешне вроде проблем никаких - база целая, удалённые строки удалены. Но эта ошибка нервирует, и я уже всю голову себе разбил в попытках понять, в чем же может быть дело. Гугл ничего дельного не выдал по этому поводу.

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# Основное окно
 
# Объявляю переменную
self.history_db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
 
# Открываю новое окно
self.history_browser_window = HistoryBrowserClass(self, self.history_file, self.history_db,
                                                              self.get_profile_file_name(self.profile_file, False),
                                                              self.history_browser_window_geometry)
self.history_browser_window.show()
 
# При закрытии программы:
if self.history_db.isOpen():
    self.history_db.close()
 
 
 
# Второе окно
class HistoryBrowserClass(QtWidgets.QWidget):
 
    def __init__(self, parent, history_file, history_db, profile_name, geometry):
        super().__init__()
        ...........................
        self.history_db = history_db
        self.model_history = QtSql.QSqlTableModel(self.ui.tbl_history)
        self.model_history.setTable('history')
        self.model_history.select()
        self.ui.tbl_history.setModel(self.model_history)
 
        # Отрывок из метода с удалением строк из базы
        to_delete = ''
        for i in highlighted_row_names_list:
            if to_delete:
                to_delete += ' OR '
            to_delete += 'path = "' + i + '"'
        query_text = ('DELETE FROM history WHERE ' + to_delete + ';')
        query = QtSql.QSqlQuery()
        query.prepare(query_text)
        query.exec()
 
        # При закрытии окна
        if self.history_db.isOpen():
            self.history_db.close()
Как то так. Вроде ничего не забыл привести. Что меня ещё удивляет - почему то необязательно открывать базу при открытии второго окна. Каким то образом она открывается сама.

И ещё - попробовал ту же базу открыть в другом тестовом приложении, и выполнить те же действия, там ошибки нет. Правда там нет и передачи в другое окно.

Буду весьма признателен за подсказку.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.12.2023, 18:21
Ответы с готовыми решениями:

Ошибка сегментации при работе со строками
Задача: Дан файл содержащий строки вещественных чисел. Вычислить минимум и максимум в каждой строке. Результат записать в файл. ...

Ошибка сегментации при работе с отсортированным списком
Использую стандартный алгоритм сортировки qSort: qSort(PolygonList.begin(),PolygonList.end()); в polygonlist содержатся объекты...

Ошибка при работе с sqlite Parameter count mismatch
textQuery выглядит так: INSERT INTO tbl_picture (id_picture, name_picture, data_picture) VALUES ('1', 'test picture', :imageData); ...

16
290 / 205 / 68
Регистрация: 18.09.2019
Сообщений: 407
Записей в блоге: 58
10.12.2023, 19:35
eol3000, если Вы открываете второе соединение, то ему надо дать уникальное имя (см. QSqlDatabase.addDatabase()), иначе
Warning: If you add a connection with the same name as an existing connection, the new connection replaces the old one. If you call this function more than once without specifying connectionName, the default connection will be the one replaced.
Добавлено через 30 минут
Добавлю, что по умолчанию используется имя qt_sql_default_connection
0
0 / 0 / 0
Регистрация: 28.06.2021
Сообщений: 17
10.12.2023, 20:06  [ТС]
Прошу прощения, я в теме баз данных пока сильно начинающий, и не совсем понял, о каком имени, первом и втором идёт речь ?
0
290 / 205 / 68
Регистрация: 18.09.2019
Сообщений: 407
Записей в блоге: 58
10.12.2023, 20:40
Применение вот этого определения
C++
1
QSqlDatabase QSqlDatabase::addDatabase(const QString &type, const QString &connectionName = QLatin1String(defaultConnection))
в переводе на Python для SQLITE означает запрос нового соединения new_conn
Python
1
new_conn = QSqlDatabase.addDatabase('QSQLITE', 'my_second_connection')
c именем my_second_connection.

Добавлено через 7 минут
Видимо, где-то по тексту Вы повторно запрашиваете открытие
Python
1
db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
с именем по умолчанию
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,764
10.12.2023, 22:37
Цитата Сообщение от eol3000 Посмотреть сообщение
почему то необязательно открывать базу при открытии второго окна. Каким то образом она открывается сама.
в примерах открытие БД вообще в отдельной функции
https://github.com/pyqt/exampl... ficial/sql
0
0 / 0 / 0
Регистрация: 28.06.2021
Сообщений: 17
11.12.2023, 20:21  [ТС]
В том то и дело, что addDatabase нет больше нигде.
Сейчас попробовал задать имя наподобие этого:
new_conn = QSqlDatabase.addDatabase('QSQLITE', 'my_second_connection')
и таблица открылась пустая, т.е. похоже, что база не подключилась. Наверное, это имя ещё где то надо указывать ?
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,764
11.12.2023, 20:55
Цитата Сообщение от eol3000 Посмотреть сообщение
то имя ещё где то надо указывать ?
конечно.
sqlite - файловая БД
Python
1
2
3
4
5
6
7
8
9
def createConnection():
    db = QSqlDatabase.addDatabase('QSQLITE')
    db.setDatabaseName('my_database.sqlite')
    if not db.open():
        QMessageBox.critical(None, "Cannot open database",
            db.lastError().text(),
                QMessageBox.Cancel)
        return False
    return True
Добавлено через 1 минуту
если вы вводите несуществующее имя - просто пустой файл будет создан my_database.sqlite
0
 Аватар для kapbepucm
1568 / 741 / 321
Регистрация: 02.05.2020
Сообщений: 1,660
11.12.2023, 20:56
Цитата Сообщение от eol3000 Посмотреть сообщение
и таблица открылась пустая, т.е. похоже, что база не подключилась.
Если Вы создаёте второе подключение то и объекты запросов и отображалки надо указывать с каким им соединением работать- они по умолчанию все тоже работают с тем первым дефотным.

В Qt вообще с базами данных довольно всё замудрено IMHO. Там какбы думано- открыл базу и не закрываешь её до конца приложения, но если всёже надо закрыть, там надо немного поизвращаться.
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,764
12.12.2023, 00:23
Цитата Сообщение от kapbepucm Посмотреть сообщение
В Qt вообще с базами данных довольно всё замудрено IMHO. Там какбы думано- открыл базу и не закрываешь её до конца приложения, но если всёже надо закрыть, там надо немного поизвращаться.
закрыть то можно
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class View(QMainWindow):
    def __init__(self,parent=None):
        super().__init__(parent)
        self.db = QSqlDatabase.addDatabase('QSQLITE')
 
    def open_db(self,dbname):
        if self.db.isOpen(): 
            self.db.close()
        self.db.setDatabaseName(dbname)
        if not self.db.open():
            QMessageBox.critical(self, "Cannot open database",
                self.db.lastError().text(),
                QMessageBox.Cancel)
            return
так я делал

Добавлено через 3 часа 15 минут
Цитата Сообщение от kapbepucm Посмотреть сообщение
В Qt вообще с базами данных довольно всё замудрено IMHO
ну что там замудрено - соединение создается как бы неявно в отличие от sqlite3.connect
базы то все разные, и приложение обычно пишется под конкретную БД
я сравнивал два варианта с одинаковым функционалом - sqlite3 vs QtSql - на больших обьемах данных Qt намного шустрее
0
 Аватар для kapbepucm
1568 / 741 / 321
Регистрация: 02.05.2020
Сообщений: 1,660
12.12.2023, 00:51
Цитата Сообщение от vic5710 Посмотреть сообщение
закрыть то можно
там по хорошему ещё connection надо рвать с помощью removeDatabase, это антипод addDatabase

Добавлено через 1 минуту
Цитата Сообщение от vic5710 Посмотреть сообщение
соединение создается как бы неявно
угу, и с этим надо всё время считаться
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,764
12.12.2023, 01:41
Цитата Сообщение от eol3000 Посмотреть сообщение
query = QtSql.QSqlQuery()
        query.prepare(query_text)
        query.exec()
ИМХО prepare тут ни к чему
Python
1
2
if not query.exec(query_text):
    print(query.lastError().text()
0
290 / 205 / 68
Регистрация: 18.09.2019
Сообщений: 407
Записей в блоге: 58
12.12.2023, 19:08
Цитата Сообщение от kapbepucm Посмотреть сообщение
там по хорошему ещё connection надо рвать с помощью removeDatabase, это антипод addDatabase
А рвать его можно только вне области видимости соединения
Но зато это и позволяет работать из дополнительных потоков...
0
 Аватар для kapbepucm
1568 / 741 / 321
Регистрация: 02.05.2020
Сообщений: 1,660
12.12.2023, 20:27
Цитата Сообщение от iamvic Посмотреть сообщение
А рвать его можно только вне области видимости соединения
ну это просто хороший путь, однако необязательный, главное, чтобы сборщик мусора грохнул нужный объект когда надо, а не когда ненадо

Добавлено через 2 минуты
Цитата Сообщение от vic5710 Посмотреть сообщение
ИМХО prepare тут ни к чему
разрешите докопаться через prepare оно более универсальнее, там и bindValues можно потом прикручивать, пусть ТС сразу к хорошему приучается
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,764
12.12.2023, 22:39
Цитата Сообщение от kapbepucm Посмотреть сообщение
там и bindValues можно потом прикручивать
это нужно если используются внешние данные
http://qt-doc.ru/ispolzovanie-komand-sql-v-qt.html

Добавлено через 8 минут
Цитата Сообщение от kapbepucm Посмотреть сообщение
там по хорошему ещё connection надо рвать с помощью removeDatabase, это антипод addDatabase
по тому же доку addDatabase() активирует драйвер БД всего лишь
http://qt-doc.ru/soedinenie-s-bazoj-dannyh-qt.html

Добавлено через 2 минуты
а насчет закрытия БД -
void QSqlDatabase::close ()
Закрывает соединения с базой данных, освобождает занятые ресурсы и делает недействительными все существующие объекты QSqlQuery, которые использовались вместе с базой данных.
0
0 / 0 / 0
Регистрация: 28.06.2021
Сообщений: 17
13.12.2023, 20:19  [ТС]
Спасибо всем большое за ответы!
Учитывая всё вышесказанное, поэкспериментировал, и немного опять запутался.
Если имя соединения не задавать, примерно вот так:
Python
1
self.history_db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
то таблица открывается. При этом:
Python
1
2
self.model_history = QtSql.QSqlTableModel(self.ui.tbl_history)
print(self.model_history.database().connectionName())
Выводит qt_sql_default_connection

Если же имя соединения задать, примерно вот так:
Python
1
self.history_db = QtSql.QSqlDatabase.addDatabase('QSQLITE','first_connection')
тогда таблица не открывается, программа падает в sigsegv на этапе вывода таблицы, а print выдаёт пустую строку.
Как я могу задать имя соединения при создании модели ? Пока не нашёл ничего подходящего. И можно ли считать создание модели вторым подключением к базе ? Может как раз тут мне следует задать другое имя подключения ?
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,764
13.12.2023, 21:34
нужно ли вам сразу две БД использовать?
и если используете запросы - используйте лучше QSqlQueryModel
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from PyQt5.QtWidgets import QApplication,QTableView
from PyQt5.QtSql import QSqlDatabase, QSqlQuery, QSqlQueryModel
from PyQt5.QtCore import QTimer
import time
 
app = QApplication([])
 
 
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName('orders.db')
if not db.open():
    print(db.lastError().text())
print(db.tables())
 
QSqlDatabase.addDatabase("QSQLITE","myDB")
db1 = QSqlDatabase.database("myDB")
db1.setDatabaseName('payments.db')
if not db1.open():
    print(db1.lastError().text())
print(db1.tables())
 
model = QSqlQueryModel()
view = QTableView()
view.setModel(model)
view.show()
view.move(0,0)
 
model.setQuery('select * from {}'.format(db.tables()[-1]),db)
input('?')
model.setQuery('select * from {}'.format(db1.tables()[-1]),db1)
 
db.close()
db1.close()
app.exec()
0
 Аватар для kapbepucm
1568 / 741 / 321
Регистрация: 02.05.2020
Сообщений: 1,660
14.12.2023, 17:28
Цитата Сообщение от eol3000 Посмотреть сообщение
тогда таблица не открывается, программа падает в sigsegv на этапе вывода таблицы, а print выдаёт пустую строку
какой нибудь минимальный запускабельный пример, воспоизводящий проблему покажите, а то со слов сложно угадать, что там не так
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
14.12.2023, 17:28
Помогаю со студенческими работами здесь

QtSQL + SQLite = trouble
добрый день, подскажите пожалуйста такую вот вещь: есть база данных SQLite, работаю с ней с помощью Qt-шных функций, в debug режиме файл...

Ошибка при подключении к базе данных QtSql
Весь день ломаю голову над ошибкой, перечитал все что возможно и изменял все что только можно, но решения найти не могу. Сама ошибка: ...

Аппаратная ошибка видео (Ошибка при работе с видеоустройствами привела к некорректной работе Windows).
Аппаратная ошибка видео. Последнее время во время игры Call of Duty: Modern Warfare 2 в мультиплеер, (между сменами карт, как только...

Ошибка сегментации при работа с strncat()
Доброго времени суток. Столкнулся с проблемой: Я написал функцию, которая в заданной строчке во всех словах удаляет все буквы, совпадающие...

Ошибка сегментации при освобождении памяти
Вот в упор не понимаю, почему программа вылетает уже на завершающем этапе. Пожалуйста, посмотрите, что не так // для тестирования ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это дополнительная запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru