Ниже разберём основные причины, почему условие if 'good' not in con.tables(): может вести себя «странно» и в итоге мешать созданию таблицы.
1. Таблица «good» уже существует в базе, а вы смотрите не туда
Частый сценарий с SQLite:
- Скрипт уже когда-то успешно создал таблицу «good»,
- Файл data.sqlite лежит в том же каталоге (или в каком-то другом),
- При запуске проверка if 'good' not in con.tables(): возвращает False, потому что в этой базе таблица уже есть.
Но вы, возможно, смотрите в другую копию data.sqlite (или просто не обновили вкладку в какой-нибудь SQLite-браузере и не видите там таблицу).
Попробуйте:
Python:
print(con.databaseName()) # посмотрите, какой именно файл открыт
print(con.tables()) # выведите все таблицы
Если в выводе будет ['good'], значит таблица уже там.
Если файл не тот, что ожидается, — поправьте путь в con.setDatabaseName(...).
2. Проверка проходит, но ничего не происходит из-за проблем с открытием базы
Иногда база не открывается (например, из-за отсутствия прав записи или к базе нет доступа).
Убедитесь, что:
Python:
if not con.open():
print("Не удалось открыть базу данных!", con.lastError().text())
Если база не открывается, con.tables() будет выдавать пустой список (в большинстве случаев). Но тогда и query.exec(...) работать корректно не будет. В таких случаях всегда проверяйте результат
open() и
lastError().
3. Неявная транзакция не подтверждена (редко, но бывает)
В стандартном режиме SQLite в PyQt/QT-SQL изменения, как правило, применяются сразу (Auto-commit). Но если вы вдруг включили транзакции вручную (например, con.transaction()), нужно после query.exec(...) вызвать con.commit(). Иначе изменения не сохранятся.
В вашем коде транзакций не видно, так что, скорее всего, это не ваш случай.
4. Особенности регистров и имён таблиц
con.tables() возвращает список таблиц в том виде, в каком они хранятся в метаданных СУБД. Обычно SQLite приводит имена к нижнему регистру, но всякое бывает.
Чаще всего, если вы создали таблицу good, в списке тоже будет 'good'. Но на всякий случай можно сделать:
Python:
tables_in_db = [t.lower() for t in con.tables()]
if 'good' not in tables_in_db:
...
Таким образом вы исключите «шальные» расхождения по регистру (но в обычной практике с SQLite это не проблема).
5. Вы не закрыли соединение или не освободили курсор перед con.tables()
Иногда (особенно в более старых версиях PyQt5/PyQt6) после query.exec(...) нужно «освободить» этот query, прежде чем вызывать con.tables(). Но в вашем примере порядок такой:
- con.open()
- if 'good' not in con.tables(): ...
- con.close()
— здесь всё выглядит нормально. Если таблица не существовала, она должна создаться. Если она была, то if ... not in ... не сработает.
6. Наконец, самый банальный сценарий: логика
Если вы раньше
уже запускали этот скрипт с закомментированным if и таблица успешно создалась, то теперь:
- Таблица физически уже есть в data.sqlite.
- Естественно, if 'good' not in con.tables() вернёт False.
- Строка с create table ... не выполняется.
- Вы смотрите в «тот же» data.sqlite и говорите: «Почему она не создаётся?!» — потому что она уже существует.
Что делать, чтобы «убедиться»?
- Удалите или переименуйте файл data.sqlite, чтобы начать «с чистого листа».
- Запустите ваш код снова с условием if 'good' not in con.tables():.
- Добавьте отладочные print(...):
Python:
from PyQt6 import QtWidgets, QtSql
import sys
app = QtWidgets.QApplication(sys.argv)
con = QtSql.QSqlDatabase.addDatabase('QSQLITE')
con.setDatabaseName('data.sqlite')
if not con.open():
print("Не удалось открыть базу данных:", con.lastError().text())
else:
print("База данных открыта:", con.databaseName())
print("Таблицы в БД до проверки:", con.tables())
if 'good' not in con.tables():
print("Таблица 'good' не найдена, создаём...")
query = QtSql.QSqlQuery()
res = query.exec("CREATE TABLE good ("
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"goodname TEXT, "
"goodcount INTEGER)")
print("Результат CREATE TABLE =", res, "Ошибки:", query.lastError().text())
else:
print("Таблица 'good' уже существует, пропускаем создание.")
con.close()
- После выполнения посмотрите, что выведется.
- Если увидите: «Таблица 'good' уже существует» и в итоге таблица там действительно есть, значит всё нормально.
- Если вывелось, что таблица не найдена, а потом «Результат CREATE TABLE = True», значит она создалась.
- Если выводятся ошибки (например, «unable to open database file»), нужно разбираться с правами/путями.
В итоге
Судя по всему, в вашем случае причина проста:
таблица «good» уже есть, поэтому условие if 'good' not in con.tables(): не выполняется. Именно поэтому при закомментированной проверке (вызывается create table без всяких условий) вы «замечаете», что таблица «будто бы создаётся».
Это нередкая ситуация при работе с локальными файлами SQLite:
- люди забывают, что файл «data.sqlite» уже где-то лежит,
- скрипт (или IDE) запускается из другой папки,
- а потом удивляются, почему при проверке con.tables() всегда видна эта таблица.
Попробуйте по шагам проверить пути/файлы, удалить «старый» data.sqlite и добавить print(...) в отладку — всё станет ясно.
Удачи в дальнейшей разработке!