@Derton1332

При добавлении пользователя в таблицу в поле ID ставиться none, хотя я сделал проверку, пользователю присваивается ID. Что не так?

Здравствуйте. Столкнулся с проблемой. При добавление пользователя в таблицу в самой таблице отображается значение none. Проверка присваивания ID показала, что ID был присвоен данному добавленному пользователю. Прошу помочь, весь мозг сломал, что не так

import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import sqlite3
import pandas as pd
import re

# Подключение к базе данных SQLite
conn = sqlite3.connect('customers.db')
cursor = conn.cursor()

# Создание таблицы, если она еще не существует
cursor.execute('''
    CREATE TABLE IF NOT EXISTS customers (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        last_name TEXT NOT NULL,
        first_name TEXT NOT NULL,
        middle_name TEXT,
        city TEXT,
        phone TEXT NOT NULL
    )
''')
conn.commit()

# Функции для работы с базой данных
def add_customer(last_name, first_name, middle_name, city, phone):
    cursor.execute('''
        INSERT INTO customers (last_name, first_name, middle_name, city, phone) 
        VALUES (?, ?, ?, ?, ?)
    ''', (last_name, first_name, middle_name, city, phone))
    conn.commit()
    new_id = cursor.lastrowid  # Получаем ID новой записи
    update_customer_list()
    return new_id


def delete_customer(customer_id):
    cursor.execute('DELETE FROM customers WHERE id = ?', (customer_id,))
    conn.commit()
    update_customer_list()

def search_customers(id, last_name, first_name, middle_name, city, phone):
    cursor.execute('''
        SELECT * FROM customers WHERE
        (id = ? OR ? = '') AND
        (last_name LIKE ? OR ? = '') AND
        (first_name LIKE ? OR ? = '') AND
        (middle_name LIKE ? OR ? = '') AND
        (city LIKE ? OR ? = '') AND
        (phone LIKE ? OR ? = '')
    ''', (id, id, f'%{last_name}%', last_name, f'%{first_name}%', first_name, f'%{middle_name}%', middle_name, f'%{city}%', city, f'%{phone}%', phone))
    return cursor.fetchall()

def get_all_customers():
    cursor.execute('SELECT * FROM customers')
    return cursor.fetchall()    
    
# Функция обновления списка пользователей
def update_customer_list():
    for row in tree.get_children():
        tree.delete(row)
    for row in get_all_customers():
        tree.insert('', tk.END, values=row)

# Функция сортировки данных в таблице
def treeview_sort_column(tv, col, reverse):
    l = [(tv.set(k, col), k) for k in tv.get_children('')]
    
    # Попробуем сортировать значения в зависимости от того, являются ли они числовыми или текстовыми
    try:
        l.sort(key=lambda t: int(t[0]) if t[0] and t[0].isdigit() else float('inf'), reverse=reverse)
    except ValueError:
        # Если преобразование не удалось, значит, столбец текстовый
        l.sort(key=lambda t: t[0] or '', reverse=reverse)

    # Перемещаем строки в `Treeview` согласно отсортированному списку
    for index, (_, k) in enumerate(l):
        tv.move(k, '', index)
    
    # Переключаем направление сортировки для следующего клика по заголовку
    tv.heading(col, command=lambda _col=col: treeview_sort_column(tv, _col, not reverse))

   # Функция для проверки ввода (допускаются только цифры)
def validate_phone(P):
    if P.isdigit() or P == "":
        return True
    return False
   
# Функция для добавления пользователя
def add_customer_dialog():
    def submit():
        phone_number = '+7' + phone_entry.get()
        if not re.match(r'^\+7\d{10}$', phone_number):
            messagebox.showerror("Ошибка", "Неверный формат телефона. Используйте формат +7XXXXXXXXXX (только цифры)")
            return
        new_id = add_customer(last_name_entry.get(), first_name_entry.get(), middle_name_entry.get(), city_entry.get(), phone_number)
        messagebox.showinfo("Успех", f"Пользователь добавлен с ID: {new_id}")
        add_window.destroy()
        
    add_window = tk.Toplevel(root)
    add_window.title("Добавить пользователя")

    tk.Label(add_window, text="Фамилия").grid(row=0, column=0)
    last_name_entry = tk.Entry(add_window)
    last_name_entry.grid(row=0, column=1)

    tk.Label(add_window, text="Имя").grid(row=1, column=0)
    first_name_entry = tk.Entry(add_window)
    first_name_entry.grid(row=1, column=1)

    tk.Label(add_window, text="Отчество").grid(row=2, column=0)
    middle_name_entry = tk.Entry(add_window)
    middle_name_entry.grid(row=2, column=1)

    tk.Label(add_window, text="Город").grid(row=3, column=0)
    city_entry = tk.Entry(add_window)
    city_entry.grid(row=3, column=1)

    tk.Label(add_window, text="Телефон +7").grid(row=4, column=0)
    phone_entry = tk.Entry(add_window, validate="key", validatecommand=(root.register(validate_phone), '%P'))
    phone_entry.grid(row=4, column=1)

    # Ограничение длины номера телефона до 10 цифр (не включая +7)
    phone_entry.bind('<KeyRelease>', lambda e: phone_entry.delete(10, 'end') if len(phone_entry.get()) > 10 else None)

    tk.Button(add_window, text="Добавить", command=submit).grid(row=5, column=0, columnspan=2)

# Функция для удаления пользователя
def delete_customer_dialog():
    selected_item = tree.selection()[0]
    customer_id = tree.item(selected_item)['values'][0]
    delete_customer(customer_id)

# Функция для поиска пользователей
def search_customers_dialog():
    def search():
        result = search_customers(
            id_entry.get(), 
            last_name_entry.get(), 
            first_name_entry.get(), 
            middle_name_entry.get(), 
            city_entry.get(), 
            phone_entry.get()
        )
        for row in tree.get_children():
            tree.delete(row)
        for row in result:
            tree.insert('', tk.END, values=row)
        messagebox.showinfo("Результаты поиска", f"Найдено записей: {len(result)}")
        search_window.destroy()

    search_window = tk.Toplevel(root)
    search_window.title("Поиск клиентов")

    tk.Label(search_window, text="ID").grid(row=0, column=0)
    id_entry = tk.Entry(search_window)
    id_entry.grid(row=0, column=1)

    tk.Label(search_window, text="Фамилия").grid(row=1, column=0)
    last_name_entry = tk.Entry(search_window)
    last_name_entry.grid(row=1, column=1)

    tk.Label(search_window, text="Имя").grid(row=2, column=0)
    first_name_entry = tk.Entry(search_window)
    first_name_entry.grid(row=2, column=1)

    tk.Label(search_window, text="Отчество").grid(row=3, column=0)
    middle_name_entry = tk.Entry(search_window)
    middle_name_entry.grid(row=3, column=1)

    tk.Label(search_window, text="Город").grid(row=4, column=0)
    city_entry = tk.Entry(search_window)
    city_entry.grid(row=4, column=1)

    tk.Label(search_window, text="Телефон").grid(row=5, column=0)
    phone_entry = tk.Entry(search_window)
    phone_entry.grid(row=5, column=1)

    tk.Button(search_window, text="Поиск", command=search).grid(row=6, column=0, columnspan=2)

# Создание таблицы для отображения данных
columns = ("ID", "Фамилия", "Имя", "Отчество", "Город", "Телефон")
tree = ttk.Treeview(frame, columns=columns, show="headings")
for col in columns:
    tree.heading(col, text=col, command=lambda _col=col: treeview_sort_column(tree, _col, False))
    
    tree.grid(row=0, column=0, sticky='nsew')
  • Вопрос задан
  • 86 просмотров
Решения вопроса 1
Vindicar
@Vindicar
RTFM!
Ты эту БД давно используешь? Просто новички часто споыткаются о простой факт. Запросы вида CREATE TABLE IF NOT EXISTS создадут отсутствующую таблицу, но не изменят таблицу, если она уже существует. Даже если структура таблицы отличается от заданной. Скажем, если ты добавил автоинкремент в запрос CREATE позднее, то в реальной таблице его не будет.
В таком случае проще всего снести файл базы, чтобы она пересоздалась, и снова наполнить его данными.

Также можешь попробовать узнать реальную структуру твоей таблицы так:
SELECT sql FROM sqlite_schema WHERE type = 'table' AND name = 'customers'
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы