Search code examples
pythonsql-servertkinterpypyodbc

How do I place a tkinter variable in a Pypyodbc server name?


I am pulling a variable from the user when they select one of the radio buttons I provide them. Each radio button variable is set as an actual server I can normally connect to using MsSql.

My below code has a !!!!!!!!!!!!! MY EXAMPLE !!!!!!!!!!!!!!!!!! listed next to the spot I am trying to figure out.

I get a connection error when I use pypyodbc.connect ('Server=serverName;'), but I know it works if I get rid of the radio button variable and enter the actual server name.

Any ideas?

#! /usr/bin/python
import os
import pypyodbc
import tkinter
from tkinter import ttk


class Adder(ttk.Frame):
    """The adders gui and functions."""
    def __init__(self, parent, *args, **kwargs):
        ttk.Frame.__init__(self, parent, *args, **kwargs)
        self.root = parent
        self.init_gui()

    def on_quit(self):
        """Exits program."""
        quit()

    def calculate(self):
        serverName = str(self.selectedTown.get())  #! !!!!!!!!!!!!! MY EXAMPLE  !!!!!!!!!!!!!!!!!!
        word1 = str(self.workstation1_entry.get())
        # num2 = int(self.localid2_entry.get())  # This will be entered in a later statement where user can enter LocationID
        # if str(self.selectedTown.get()) in str(self.selectedTown.get()):
        connection = pypyodbc.connect('Driver={SQL Server};'  #! !!!!!!!!!!!!! MY EXAMPLE  !!!!!!!!!!!!!!!!!!
                                            'Server=serverName;'
                                            'Database=mydatabase;'
                                            'Trusted_Connection=yes;')
        cursor = connection.cursor() 
        SQLCommand = ("SELECT Name, Location_ID "      
            "FROM dbo.PB_Location "
            "WHERE Name = ?")
        Values = [word1]
        cursor.execute(SQLCommand,Values)
        results = cursor.fetchone()
        if results:
            self.answer_label['text'] = str(results[1]) # displays answer
            connection.close()
        else:
            self.answer_label['text'] = "Invalid"
        connection.close()



    def init_gui(self):
        """Builds GUI."""
        self.root.title('ID Lookup')
        self.root.option_add('*tearOff', 'FALSE')

        self.grid(column=0, row=0, sticky='nsew')

        self.menubar = tkinter.Menu(self.root)

        self.menu_file = tkinter.Menu(self.menubar)
        self.menu_file.add_command(label='Exit', command=self.on_quit)

        self.menu_edit = tkinter.Menu(self.menubar)

        self.menubar.add_cascade(menu=self.menu_file, label='File')
        self.menubar.add_cascade(menu=self.menu_edit, label='Edit')

        self.root.config(menu=self.menubar)

        self.workstation1_entry = ttk.Entry(self, width=5)
        self.workstation1_entry.grid(column=1, row = 2)

        self.localid2_entry = ttk.Entry(self, width=5)
        self.localid2_entry.grid(column=3, row=2)

        self.calc_button = ttk.Button(self, text='Submit',
                command=self.calculate)
        self.calc_button.grid(column=0, row=3, columnspan=4)

        self.answer_frame = ttk.LabelFrame(self, text='Answer',
                height=100)
        self.answer_frame.grid(column=0, row=4, columnspan=4, sticky='nesw')

        self.answer_label = ttk.Label(self.answer_frame, text='')
        self.answer_label.grid(column=0, row=0)


        self.selectedTown = tkinter.StringVar()
        self.selectedTown.set('b1') # make it where the top radio button is selected by default

        self.b1 = ttk.Radiobutton(self, text='Texas', value='1srvodbx', variable=self.selectedTown).grid(sticky='W', column=0,row=6, columnspan=1)  # sticky W to align everything to left          
        self.b2 = ttk.Radiobutton(self, text='Oklahoma', value='2srvodbx', variable=self.selectedTown).grid(sticky='W', column=0,row=7, columnspan=1)
        self.b3 = ttk.Radiobutton(self, text='Idaho', value='3srvodbx', variable=self.selectedTown).grid(sticky='W', column=0,row=8, columnspan=1)

        self.selectedTown.get()

        # Labels that remain constant throughout execution.
        ttk.Label(self, text='Location ID Finder').grid(column=0, row=0,
                columnspan=4)
        ttk.Label(self, text='Name').grid(column=0, row=2,
                sticky='w')
        ttk.Label(self, text='Location ID').grid(column=2, row=2,
                sticky='w')

        ttk.Separator(self, orient='horizontal').grid(column=0,
                row=1, columnspan=4, sticky='ew')

        for child in self.winfo_children():
            child.grid_configure(padx=5, pady=5)

if __name__ == '__main__':
    root = tkinter.Tk()
    Adder(root)
    root.mainloop()

Solution

  • IIUC the problem is you cannot just plug in a variable name like that. You'll have to do:

    connstr = '''Driver={{SQL Server}};Server={};Database=mydatabase;Trusted_Connection=yes;'''.format(serverName)
    connection = pypyodbc.connect(connstr)