Извлеките поле базы данных с помощью 2 комбинированных комбинаций. Проблема в функции извлечения

#python #sql #python-3.x #sqlite #tkinter

Вопрос:

Выбрав два комбинированных поля (в сочетании с привязкой), я хотел бы извлечь идентификатор поля из таблицы 1 и вставить его в таблицу 2. У меня нет проблем с извлечением поля на основе комбинированного поля, но у меня есть проблемы с извлечением поля на основе 2 комбинированных полей, потому что они объединены друг с другом. Проблема заключается только в функции def id_rounds ().

У меня есть два комбо-бокса: один, в котором я выбираю название «Турнира», и другой, в котором я выбираю количество раундов (от 1 до 38 различных раундов для каждого турнира). Чтобы выбрать, какому турниру должен соответствовать идентификатор турнира, я использую combobox combo_Tournaments и функцию def combo_tournaments; в то время как для выбора номера раунда я использую combobox combo_Rounds и функцию combo_rounds. При выборе Турнира и / или Раунда также автоматически вводится соответствующий идентификатор (а также фактические данные). Таким образом, каждая комбинация содержит по 2 элемента, в общей сложности 4.

Вот база данных:

 CREATE TABLE "All_Tournament" (
    "ID_Tournament" INTEGER,
    "Tournament" TEXT,
    PRIMARY KEY("Tournament" AUTOINCREMENT)
);

    CREATE TABLE "All_Round" (
        "ID_Round"  INTEGER,
        "Number_Round"  INTEGER,
        "ID_Tournament" INTEGER,
        PRIMARY KEY("ID_Round" AUTOINCREMENT),
    );
 

ПРОБЛЕМА: В настоящее время, когда я писал код функции def id_rounds(), идентификатор выбранного раунда сохраняется, но без точного соответствия выбранному турниру в выпадающем списке Турниров. Проблема в том, что каждый Турнир состоит из 38 различных раундов, поэтому в таблице All_Round числа от 1 до 38 повторяются несколько раз, каждое из которых соответствует идентификатору турнира. Например, Серия А с 1 по 38 раунд; Серия В с 1 по 38 раундов; Премьер-лига с 1 по 38 раундов. Поэтому я хотел бы ввести идентификатор одного раунда, соответствующего Турниру (по отношению к турниру), потому что в каждом турнире от 1 до 38 раундов, поэтому для каждого турнира существует много разных «от 1 до 38 раундов».

 #Combobox Tournament
lbl_Tournament = Label(root, text="Tournament", font=("Calibri", 11), bg="#E95420", fg="white")
lbl_Tournament.place(x=6, y=60)
combo_Tournaments = ttk.Combobox(root, font=("Calibri", 11), width=30, textvariable=campionato, state="readonly")
combo_Tournaments.place(x=180, y=60)
combo_Tournaments.set("Select")
combo_Tournaments['values'] = combo_tournaments()
combo_Tournaments.bind('<<ComboboxSelected>>', combo_teams)

lbl_Rounds = Label(root, text="Rounds", font=("Calibri", 11), bg="#E95420", fg="white")
lbl_Rounds.place(x=600, y=60)
combo_Rounds = ttk.Combobox(root, font=("Calibri", 11), width=30, textvariable=rounds,  state="readonly") 
combo_Rounds.place(x=680, y=60)
combo_Rounds.set("Select")
combo_Rounds['values'] = combo_campionati()
combo_Tournaments.bind('<<ComboboxSelected>>', combo_rounds, add=True)


def combo_tournaments():
    tournaments = combo_tournaments.get()
    cursor.execute('SELECT Tournament FROM All_Tournament')
    result=[row[0] for row in cursor]
    return result

def id_tournaments():
    tournaments = combo_tournaments.get()
    cursor.execute('SELECT ID_Tournament FROM All_Tournament WHERE Tournament=?',(tournaments,))
    result=[row[0] for row in cursor]
    return result[0]

def combo_rounds(event=None):
    rounds = combo_rounds.get()        
    cursor.execute('SELECT Number_Round From All_Round WHERE ID_Tournament')
    result=[row[0] for row in cursor]
    combo_Rounds['value'] = result
    return result

#THE PROBLEM IS HERE 
def id_rounds():
    rounds = combo_rounds.get()    
    cursor.execute('SELECT ID_Round FROM All_Round WHERE Number_Round=? AND Tournament=?',(rounds, tournaments))
    result=[row[0] for row in cursor]
    return result[0]

def combo_teams(event=None):
    tournaments = combo_tournaments.get()
    cursor.execute('SELECT s.Name_Teams FROM All_Teams s, All_Tournament c WHERE s.ID_Tournament=c.ID_Tournament AND c.Tournament = ?', (tournaments,))
    result=[row[0] for row in cursor]
    combo_Teams_1['values'] = result
    combo_Teams_2['values'] = result
    return result
 

ЧТО Я ХОЧУ ПОЛУЧИТЬ? Поэтому я хотел бы получить, например, что: если из турнира комбобоксе я выбираю Серию А, а затем 1-го раунда, в таблице результатов идентификатор круга 1 должны быть введены, но вписанные в Серии А. Или, другой пример, если из турнира комбобоксе я выбираю Серию B, а затем раунд 1, идентификатор круга 1 должны быть введены в поисковой таблице, но соответствующей серии В.

ВОПРОС: Как я могу исправить функцию def id_rounds, которая вставляет номер раунда в соответствие (по отношению) к турниру? В настоящее время я ввожу только идентификатор выбранного раунда в выпадающем списке, не совпадая с чемпионатом, выбранным в выпадающем списке турнира.

Комментарии:

1. Первый id_tournament должен быть автоинкрементом, а не турниром. 2-й : В id_rounds вы не получаете турнир. 3-й вы должны выбрать один из раундов и турнирной таблицы, в которой вы присоединяетесь к id_tournament

2. Этот вопрос, похоже, не имеет никакого отношения к tkinter. Задаваемый вопрос, похоже, больше касается того, как использовать внешние ключи и/или соединения в sqlite.

3. Я не понимаю, в чем разница между ID_Round и Number_Round ?

4. @acw1668 ID_Round-это классический идентификатор записи. Number_Round будет 1, 2, 3, 4 до 38. Под Number_Round, то есть под кругом, я имею в виду недели, учитывая, что в неделю бывает один раунд. Не могли бы вы мне помочь, пожалуйста?

5. @BryanOakley Правда, ты прав. Но я ввел tkinter, потому что я использую его для приложения, например, для 2 комбинаций. Я вставил тег tkinter для полноты вопроса, даже если, как вы сказали, вам нечего делать. В любом случае, не могли бы вы мне помочь, пожалуйста? На днях вы были очень добры: вы также ответили на вопрос, похожий на этот, поэтому я предполагаю, что вы понимаете проблему. Спасибо

Ответ №1:

Ниже приведен измененный код, основанный на моем понимании:

 def combo_tournaments():
    cursor.execute('SELECT Tournament FROM All_Tournament')
    result=[row[0] for row in cursor]
    return result

def combo_rounds(event=None):
    # get all Number_Round for selected tournament
    cursor.execute('''
        SELECT Number_Round From All_Round r, All_Tournament t
        WHERE r.ID_Tournament = t.ID_Tournament AND Tournament = ?''', (campionato.get(),))
    result=[row[0] for row in cursor]
    combo_Rounds['value'] = result  # update combo_Rounds
    rounds.set('Select') # reset Rounds selection
    return result

def id_rounds(event=None):
    # get the ID_Round based on selected tournament and Number_Round
    cursor.execute('''
        SELECT ID_Round FROM All_Round r, All_Tournament t
        WHERE r.ID_Tournament = t.ID_Tournament AND Number_Round = ? AND Tournament = ?''',
        (rounds.get(), campionato.get()))
    result = cursor.fetchone()
    if result:
        print(result[0])
        return result[0]
    return None

...

campionato = StringVar()
rounds = StringVar()

#Combobox Tournament
lbl_Tournament = Label(root, text="Tournament", font=("Calibri", 11), bg="#E95420", fg="white")
lbl_Tournament.place(x=6, y=60)
combo_Tournaments = ttk.Combobox(root, font=("Calibri", 11), width=30, textvariable=campionato, state="readonly")
combo_Tournaments.place(x=180, y=60)
combo_Tournaments.set("Select")
combo_Tournaments['values'] = combo_tournaments()
combo_Tournaments.bind('<<ComboboxSelected>>', combo_rounds)

lbl_Rounds = Label(root, text="Rounds", font=("Calibri", 11), bg="#E95420", fg="white")
lbl_Rounds.place(x=600, y=60)
combo_Rounds = ttk.Combobox(root, font=("Calibri", 11), width=30, textvariable=rounds,  state="readonly")
combo_Rounds.place(x=680, y=60)
combo_Rounds.set("Select")
combo_Rounds.bind('<<ComboboxSelected>>', id_rounds)
...
 

Обратите внимание, что я использовал campionato and rounds ( StringVar ) для получения выбранного турнира и Number_Round .

Комментарии:

1. Я так вам благодарна. Я попробую и дам тебе знать позже, если все в порядке. Между тем, из уважения ко всем тем, кто высказал свои замечания, мы также ожидаем их уважения. Если кто-то, кто читает, хочет что-то добавить (прокомментировать или ответить, продолжайте). А пока еще раз спасибо вам

2. Все работает нормально. Спасибо. Теперь извлеките и сохраните ID_ROUNDS. Спасибо. Есть одна маленькая ошибка в combo_Tournaments.bind и combo_Rounds.bind. Я написал их немного по-другому, например, там также были команды combo_teams, которые будут выпадающим списком для выбора команд матча, которые будут включены в каждый раунд. Я сейчас очень устал. Я хорошо вижу завтрашний день (самое большее послезавтра, так как есть выходные), поэтому я лучше объясню свои сомнения. Тем не менее, я проголосую за вас как за лучший ответ, потому что вы решили 95% проблемы. Спасибо 🙂 Увидимся послезавтра

3. Еще раз благодарю вас за ваш ответ,я хотел бы спросить вас о 3 простых вещах, пожалуйста: 1. В combo_Tournaments.bind вы удалили мои combo_teams (он используется для выбора команд в зависимости от лиг). Поэтому мне нужны 2 вещи внутри этого bing: combo_rounds и combo_teams. Вы делаете это,чтобы добавить 2 вместе?(‘<<ComboboxSelected><ComboboxSelected>>’, combo_rounds, combo_teams)? 2. Что такое метод sql, называемый внутри идентификатора def id_rounds? Я хотел бы изучить его получше. 3. Если бы у меня не было ID_Tournament внутри таблицы All_Round, пришлось бы мне использовать ВНУТРЕННЕЕ СОЕДИНЕНИЕ для подключения к ID_Tournament All_Tournament? Спасибо

4. Ваш вопрос заключается в том , как получить на ID_Round основе выбранного Tournament и Number_Round , поэтому мой ответ покажет только необходимые изменения для решения вопроса, и я думаю, что это так.

5. Ты прав, прости меня. Просто скажите мне одну вещь, пожалуйста: если бы я написал SQL-код с помощью JOIN (ВНУТРЕННИЙ?) в cursor.execute, было бы то же самое? Будет ли это по-прежнему работать правильно? Я проголосовал за ваш ответ. Тысяча благодарностей. Вы были добры ко мне