I have normalised three tables (Product, ProductType and ProductGender) and I'm looking to call them in my main program so that the user can successfully enter values and the data be stored in the correct table.
Here are the SQL tables being created
def create_product_table():
sql = """create table Product
(ProductID integer,
Name text,
primary key(ProductID))"""
create_table(db_name, "Product", sql)
def create_product_type_table():
sql = """create table ProductType
(ProductID integer,
Colour text,
Size text,
Gender text,
AmountInStock integer,
Source text,
primary key(ProductID, Colour, Size, Gender)
foreign key(Gender) references ProductGender(Gender)
foreign key(ProductID) references Product(ProductID))"""
create_table(db_name, "ProductType", sql)
def create_product_gender_table():
sql = """create table ProductGender
(Gender text,
Price text,
primary key(Gender))"""
create_table(db_name, "ProductGender", sql)
Here are the SQL subroutines
def insert_data(values):
with sqlite3.connect("jam_stock.db") as db:
cursor = db.cursor()
sql = "insert into Product (Name, ProductID) values (?,?)"
cursor.execute(sql,values)
db.commit()
def insert_product_type_data(records):
sql = "insert into ProductType(Amount, Size, Colour, Source) values (?,?,?,?)"
for record in records:
query(sql,record)
def insert_product_gender_data(records):
sql = "insert into ProductGender(Gender, Price) values (?,?)"
for record in records:
query(sql, records)
def query(sql,data): #important
with sqlite3.connect("jam_stock.db") as db:
cursor = db.cursor()
cursor.execute("PRAGMA foreign_keys = ON") #referential integrity
cursor.execute(sql,data)
db.commit()
Below is the code where the user will enter the values.
if ans=="1": #1=to option 'Add Stock'
a = input("Enter Gender: ")
b = float(input("Enter Price: "))
c = int(input("Enter ProductID: "))
d = input("Enter Name: ")
e = input("Enter Size: ")
f = input("Enter Colour: ")
g = input("Enter Source: ")
h = input("Enter Amount: ")
#code calling tables should be here
Help is gratefully appreciated. Seriously not sure how to link the 3 tables with the user's input.
This is what I did before I normalised the database. So the one table in 'Product' would be updated instead of adding an already existing product. Obviously that has changed now, since I've created two new tables but I can't successfully add a product let alone edit one.
def update_product(data): #subroutine for editing stock
with sqlite3.connect("jam_stock.db") as db:
cursor = db.cursor()
sql = "update Product set Name=?, Price=?, Amount=?, Size=?, Colour=?, Source=?, Gender=? where ProductID=?"
cursor.execute(sql,data)
db.commit()
Given the code you show above, and assuming (BIG assumption, see later!) that the user never enters data for existing records, the following code should do it:
query('insert into Product (Name, ProductID) values (?,?)',
[d, c])
query('insert into ProductGender (Gender, Price) values (?,?)',
[a, b])
query('insert into ProductType (ProductID, Colour, Size, Gender, '
AmountInStock, Source) values (?,?,?,?,?,?)',
[c, f, e, a, h, g])
Your use of arbitrary single-letter variable names makes this very hard to follow, of course, but I think I got the correspondence right:-).
Much more important is the problem that you never tell us what to do if the user enters data for an already existing record in one or more of the three tables (as determined by the respective primary keys).
For example, what if Product already has a record with a ProductID of foobar and a Name of Charlemagne; and the user enters ProductID as foobar and a Name of Alexandre; what do you want to happen in this case? You never tell us!
The code I present above will just fail the whole sequence because of the attempt to insert a new record in Product with an already-existing primary key; if you don't catch the exception and print an error message this will in fact crash your whole program.
But maybe you want to do something completely different in such cases -- and there are so many possibilities that we can't just blindly guess!
So please edit your Q to clarify in minute detail what's supposed to happen in each case of primary key "duplication" in one or more table (unless you're fine with just crashing in such cases!-), and the SQL and Python code to make exactly-that happen will follow. But of course we can't decide what the semantics of your program are meant to be...!-)
Related
I am a newbie to Sql and database concepts. so I am trying to make a program which does the basic tasks done by replacing the idea of entering commands by using functions in MySQL( like creating a table in database, adding records, modifying table etc). I now want to take input from user which include column name, its datatype, its size so that user can decide the basic structure of a new column.
So , I came across something called string formatting which I used a bit to enter variables into the Sql commands. so I tried using this concept in this case. But it gives syntax error.
Can somebody suggest me a solution to this and tell me my mistake.
I apologize for my bad grammar
Thanks
here is the code
##importing mysql connector
import mysql.connector
## Creating connection object
mydb = mysql.connector.connect(
host = "localhost",
user = "root",
password = "milkshake#343",
database = 'practice'
)
## defining a cursor object
cursor_obj = mydb.cursor()
##creating a table (uncommnent to edit and execute)
def table_create():
cursor_obj.execute("CREATE TABLE test3(name VARCHAR(50),ageINT unsigned,person_id int PRIMARY KEY AUTO_INCREMENT)")
## Describing the table (uncommnent to edit and execute)
def table_desc():
cursor_obj.execute("describe test3")
for x in cursor_obj:
print(x)
##creating a function to enter values into the table
def inputer():
#taking records from user to enter in the table
name = input("please enter the name to enter into the table:")
age = int(input("please enter the age to enter into the table:"))
#Entering values into the table
cursor_obj.execute('insert into test3 values(%s,%s)',(name,age))#you may change table name here if you want
##creating a comitt option
def commit():
mydb.commit()
##function to display the whole content of the table
def whole_table():
cursor_obj.execute("select * from test3")
for x in cursor_obj:
print(x)
##adding column into the table
def column_add():
new_column = input("Enter the name of the new column:")
data_type = input("Enter the data type of new column:")
size = int(input("Enter the size of the new column:"))
cursor_obj.execute("alter table test3 add column %s %s(%s)",(new_column,data_type,size))
column_add()
commit()
I am going to add more functions in this
E.g. After launching the program:
It is in interactive mode
We are asked what name we want to create the database with;
After creating the database, the program asks us under what name to create the table in the database;
In the next step, the program asks us how many columns the table should have;
Enter the names of the mentioned number of columns and their types interactively;
Finally, create a database and a table with the columns indicated in it;
import sqlite3
connection = sqlite3.connect(input("Enter the name for base: "))
cursor = connection.cursor()
table_name = input("Enter the name for table: ")
columns_name = []
columns_amount = int(input("Enter amount of coulms and name them: "))
for item in range(columns_amount):
item = input("input theme mane of column: ")
columns_name.append(item)
cursor.execute("DROP TABLE IF EXISTS "+table_name+"" )
cursor.execute("CREATE TABLE IF NOT EXISTS "+ table_name +" ("+columns_name[0]+" INTEGER PRIMARY KEY AUTOINCREMENT ,Name TEXT, "+columns_name[1]+" TEXT, "+columns_name[2]+" TEXT, "+columns_name[3]+" TEXT )")
connection.commit()
You can just create the sql string for table creation inside the loop like -
import sqlite3
connection = sqlite3.connect(input("Enter the name for database: "))
cursor = connection.cursor()
table_name = input("Enter the name for table: ")
sql_string = "CREATE TABLE IF NOT EXISTS {} (".format(table_name)
columns_amount = int(input("Enter amount of columns: "))
for i in range(columns_amount):
column = input("input the name of column {}: ".format(i + 1))
datatype = input("input the type of column: ")
# You may want to check here whether column name and data type is valid or not
sql_string += "{} {},".format(column, datatype)
# remove the last extra comma
sql_string = sql_string[:-1]
sql_string += ")"
print(sql_string)
cursor.execute("DROP TABLE IF EXISTS {}".format(table_name))
# Finally create the table
cursor.execute(sql_string)
connection.commit()
Your code will not work because during table creation you are assuming that there are 3 columns which may not be true. So accessing those indices of columns_name might throw exception.
I've been working with Tkinter and I'm trying to get different columns from different tables in my Treeview, I'm using SQLite as database, in my first table called registers i got different columns idcard, name, surname, cellphone, address, email, etc in my second table named attendance I use to store my entries attendances by ID number I mean I got two entries cardin = entry1 and cardout = entry1 so if one of my entries match with my registers table idcard, it automatically store idcard, timein, timeout, date in my attendance table till that it works so good, but I canĀ“t get the names, surnames columns from my first table registers and store them in my second table attendace same as my idcard, timein, timeout, date (the idcard, names, surnames must match from the first table), I was trying to solve it but I falied, I really have no idea how to do it, any help thanls in advance. have a good day. Here is my code:
def botoningreso():
time = datetime.now().strftime("%I:%M%p")
date = datetime.now().strftime("%d/%m/%Y")
conn = sqlite3.connect('database.db')
c = conn.cursor()
cardin = entry1.get()
cardout = entry2.get()
c.execute('SELECT * FROM registers WHERE idcard = ? OR idcard = ?', (cardin, cardout))
if c.fetchall():
messagebox.showinfo(title='ID Registered', message='Registered Succefully')
c.execute("INSERT INTO attendance (timein, idcard, date) VALUES (?, ?, ?)", (time, cardin, date)) #Here i also wanto to save *names and surnames* from the first table *registers* that match with the idcard column.
conn.commit()
else:
messagebox.showerror(tittle=None, message='Wrong ID card')
c.close()
Assign a variable to fetched data and then index it and proceed:
data = c.fetchall()
if data:
username = data[0][1] # Access username from fetched list
surname = data[0][2] # Access surname
messagebox.showinfo(title='ID Registered', message='Registered Succefully')
c.execute("INSERT INTO attendance (timein,idcard,date,user,sur) VALUES (?,?,?,?,?)", (time,cardin,date,username,surname))
conn.commit()
It is important to assign variable to c.fetchall() as it behaves like a generator object and loses its items once its been used.
I think I have made some mistake in creating new table in SQL by mentioning its column also. Could anyone please review the code let me know your thoughts on this
db = conn.connect(
host ="Localhost",
user ="root",
passwd ="admin",
database = "EMPLOYEE_DETAILS_00"
)
cursor = db.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS Details ( User_ID VARCHAR(255), Name VARCHAR(255), Age VARCHAR(255), Occupation VARCHAR(255), Department VARCHAR(255), Salary VARCHAR(255), Address VARCHAR(255) ) ")
I need to write a nested Python dictionary into a SQL table. I'm trying to do it by using a for loop but I'm getting the following error:
Error : Couldn't process parameters
Can anyone provide me with any suggestions on this?
This is the code I'm trying to run:
user_details = {}
create_user_ID = input(" Enter the user ID : ")
user_details[create_user_ID] = {}
user_name = input(" Enter the user name : ")
user_details[create_user_ID]['Name'] = user_name
user_age = int(input(" Enter the Age : "))
user_details[create_user_ID]['Age'] = user_age
for v in user_details.values():
cols = v.keys()
vals = v.values()
sql = "INSERT INTO Details ({}) VALUES ({})".format(
', '.join(cols),
', '.join(['%s'] * len(cols)));
cursor.execute(sql, vals)
I would say your problem is at the last line, when you try to do cursor.execute(sql,(val,)).
In Python 3 dict.keys() and dict.values() doesn't return lists, but some dictionary view objects wrapping the data, so what you're getting from (val,) is a single value tuple with one dict_values object.
Try using just val as #niteshbisht suggested or list(val) or tuple(val) if that still doesn't work.
Please see also Python nested dictionary with SQL insert, as it looks like you're trying to address the same problem.
DON'T use the most obvious one (%s with %) in real code, it's open to attacks.
sql = ("INSERT INTO Details ? Values ?" ,(col, placeholders))
cursor.execute(sql,val)
At the moment I try to ask the user for input in Python, to enter some information (here: expenseID, expense, categoryID, date). But I do not know were to start. No input validation is necessary at this step.
I managed to access my database and INSERT something manually. I tried several ways of the python input function but cannot use it as a placeholder in the SQL string.
import sqlite3
with sqlite3.connect('Expenses.sqlite') as conn:
# INSERT MANUALLY
script = "INSERT INTO Expense (ExpenseId, Amount, CategoryId, Date) VALUES ('103', '43625.5', '5', '2019-01-20');"
conn.execute(script) # execute the script
conn.commit() # commit changes to the file
# INSERT USER INPUT ???
pass
This is my idea:
with sqlite3.connect('Expenses.sqlite') as conn:
amount = input("What is the amount?")
script = "SELECT * FROM Category;"
conn.execute(script)
print(script)
category = input("What is the category?")
exp_ID = "SELECT LAST ExpenseId FROM Expense);"
date = datetime.date.today()
script = "INSERT INTO Expense (ExpenseId, Amount, CategoryId, Date) VALUES (exp_ID, amount, category, date);"
conn.execute(script)
conn.commit()
pass
Finally I want to achieve that the user is asked for amount of expense, and afterwards for expense category. ExpenseID and date should be added automatically. Date format is year-month-day. Thank you very much for advice.
Use the input function to retrieve the user input
user_input = input("Expense Amount: ")
Then use placeholders with sqlite3
sql = "INSERT INTO TABLE (COLUMN) VALUES (?)"
conn.execute(sql, (user_input,))
**in response to your edit
You need to add placeholders instead of the variable names.
Something like this:
script = "INSERT INTO Expense (ExpenseId, Amount, CategoryId, Date) VALUES (?, ?, ?, ?);"
conn.execute(script, (exp_ID,amount,category,date))