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

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

10.12.2023, 18:21. Показов 1415. Ответов 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,763
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,763
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
1566 / 739 / 321
Регистрация: 02.05.2020
Сообщений: 1,654
11.12.2023, 20:56
Цитата Сообщение от eol3000 Посмотреть сообщение
и таблица открылась пустая, т.е. похоже, что база не подключилась.
Если Вы создаёте второе подключение то и объекты запросов и отображалки надо указывать с каким им соединением работать- они по умолчанию все тоже работают с тем первым дефотным.

В Qt вообще с базами данных довольно всё замудрено IMHO. Там какбы думано- открыл базу и не закрываешь её до конца приложения, но если всёже надо закрыть, там надо немного поизвращаться.
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,763
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
1566 / 739 / 321
Регистрация: 02.05.2020
Сообщений: 1,654
12.12.2023, 00:51
Цитата Сообщение от vic5710 Посмотреть сообщение
закрыть то можно
там по хорошему ещё connection надо рвать с помощью removeDatabase, это антипод addDatabase

Добавлено через 1 минуту
Цитата Сообщение от vic5710 Посмотреть сообщение
соединение создается как бы неявно
угу, и с этим надо всё время считаться
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,763
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
1566 / 739 / 321
Регистрация: 02.05.2020
Сообщений: 1,654
12.12.2023, 20:27
Цитата Сообщение от iamvic Посмотреть сообщение
А рвать его можно только вне области видимости соединения
ну это просто хороший путь, однако необязательный, главное, чтобы сборщик мусора грохнул нужный объект когда надо, а не когда ненадо

Добавлено через 2 минуты
Цитата Сообщение от vic5710 Посмотреть сообщение
ИМХО prepare тут ни к чему
разрешите докопаться через prepare оно более универсальнее, там и bindValues можно потом прикручивать, пусть ТС сразу к хорошему приучается
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,763
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,763
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
1566 / 739 / 321
Регистрация: 02.05.2020
Сообщений: 1,654
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
Ответ Создать тему
Новые блоги и статьи
изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru