If I have 3 tables
table called students (student_id,student_name)
students data: (1, john),(2, Mike),(3, Adam)
table called courses (course_id,course_name)
courses data: (1,math),(2,english),(3,science)
table called Enrollment (student_id,course_id)
enrollment data: (1,1),(1,2),(1,3),.....student cannot enroll twice in same course like (1,1),(1,1)
CREATE TABLE "enrollment" (
"student_id" INTEGER,
"course_id" INTEGER,
FOREIGN KEY("student_id") REFERENCES "students"("student_id"),
PRIMARY KEY("student_id","course_id"),
FOREIGN KEY("course_id") REFERENCES "courses"("course_id")
);
To enroll in a course:
I want to let the user enter student_id and based on student_id user enroll
When user enter course_id
my code:
def enroll(student_id,course_id):
dbase.execute(''' INSERT INTO enrollment(student_id,course_id)
VALUES(?,?)''',(student_id,course_id))
dbase.commit()
print("Record inserted")
student_id = int(input('Enter student id: ')
data = cur.execute("SELECT * FROM students WHERE student_id= ?",(student_id,))
found = data.fetchone()
if found:
course_id = int(input("Enter the course id: "))
if course_id >= 1 and course_id <= 3:
enroll(student_id,course_id)
else:
print('please try with valid course id!')
main_menu()
else:
main_menu()
student can't enroll twice in same course
How can I fix this code?
I am using python/SQLite
You don't need to create a separate enrollment table for setting course_id for a student, just add course_id field to students table. But if you need a separate table, just add a unique constraint on student_id field, add the following line to create table enrollment script, or alter that table
CONSTRAINT uc_student_id UNIQUE (student_id)
Related
i have 2 tables .
in one table i have the details about the product ,for example:book
it contains International Standard Book Number. it is the foreign key.
in another table, i have the details about the ordered book. for example: user id for the user who ordered the book and isbn number.
i want to show the user what the ordered product.
so i need to get the isbn number from order table and from that isbn number get the data from the book table.
this is for python flask.
i don't know how to get the data from another table when the userid is not common in both the tables
#app.route('/myorder',methods=['GET','POST'])
def myorder():
if request.method == 'GET':
cur=connection.cursor()
user_id=session['userid']
cur.execute("SELECT ISBN FROM orders WHERE user_id=%s",[user_id])
data=cur.fetchall()
cur.close()
return render_template('myorder.html',data=data)
i expect a single query for getting the data
You should select book details from a join query I guess :
select books.* from books join orders on books.isbn = orders.isbn
where orders.user_id = ?;
This will do the same
select books.* from books where isbn in (select isbn from orders where user_id = ?)...
So what u have is a table with Book detail and ISBN no and Another Table with the User and ISBN no. So the simplest way to get the details of the book would be this:
cur.execute("select booktable.bookdetails from booktable A, UserTable B
where A.ISBNno = B.ISBNno
and B.userID = %s", [user_id])
or if you want all the columns
cur.execute("select booktable.* from booktable A, UserTable B
where A.ISBNno = B.ISBNno
and B.userID = %s", [user_id])
I'm trying to make an expense tracker with Python and SQLite3. I've figured out how to input data and the fields are as follows:
Amount Category(Food, Leisure, Transport, Education) Description DateOfPurchase
I'm trying to create a method so I can get the sum of all the expenses of a certain category in the month and put it into a python variable (because I want to further process and create a pie chart of the different categories)
I've tried working with the SELECT SQL function but I'm not sure how to go about solving the problem
import sqlite3
import datetime
import time
connectdb = sqlite3.connect("Expenses.db")
c = connectdb.cursor()
def create_table():
c.execute("CREATE TABLE IF NOT EXISTS Expenses (Amount REAL, Category
TEXT, Description TEXT, DateOfPurchase TEXT)")
# used to input a record
def datain():
amount = float(input("Please enter the amount of money paid for the
expense"))
Today = str(datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d'))
category = str(input("Please pick a category from Food, Transport,
Leisure, Education"))
temp = ("Food", "Transport", "Leisure", "Education")
while not (category in temp):
category = str(input("Please pick a category from Food,
Transport, Leisure, Education"))
description = str(input("Please describe the expense in a few
words"))
c.execute("INSERT INTO Expenses (Amount,Category,Description,DateOfPurchase) VALUES (?,?,?,?)",
(amount, category, description, Today))
rerun = str(input("Would you like to add another item? (Yes/No)"))
if (rerun == "Yes"):
datain()
else:
connectdb.commit()
c.close()
connectdb.close()
In order to write a detailed solution, I think I'd need to see the schema for your database. However, I think the gist of what you're trying to achieve is something like:
query = "SELECT SUM(Amount) FROM Expenses WHERE Month = ?;"
c.execute(query, theMonth)
result = c.fetchone()
And then result will be the Python variable you wanted to create.
I'm running a student database and using python 2.7 on pycharm. Here is the script
FirstName = input("Enter the Student's first name")
if not FirstName or type(FirstName) != str:
print("Enter a real name silly")
exit()
and the create Table stement looks like so
drop table if exists StudentID;
drop table if exists FirstName;
drop table if exists LastName;
drop table if exists GPA;
drop table if exists Major;
drop table if exists FacultyAdvisor;
CREATE TABLE Student(
StudentID int PRIMARY KEY AUTOINCREMENT ,
FirstName varchar(25),
LastName varchar(25),
GPA NUMERIC,
Major varchar(10),
FacultyAdvisor varchar(25)
)
and the error I'm getting is
FirstName = input("Enter the Student's first name")
File "<string>", line 1, in <module>
NameError: name 'john' is not defined
My guess is that you're using Python2
You need to use the raw_input() method when receiving String input from the user:
FirstName = raw_input("Enter the Student's first name")
I am currently having an issue with importing data to a sqlite3 table.
In my TEST program, users input their fake information when asked for an input.
I then take that input and put it in my Table, however, I am having an issue with the AutoIncrementing "User ID". Each user gets their own ID, and so far there are 5 users. When a new User inputs their data, how do I make it so it automatically sets "UserID" to the next number, in this case 6.
Everything works if I manually put "6" in the first Value (in the following code), but how do I make that automatic?
conn = sqlite3.connect('xxxxxxx.db')
c=conn.cursor()
NameCreate = input("Please enter your First and Last name: ")
UserNameCreate = input("Please enter your desired User Name: ")
PasswordCreate = input("Please enter your desired Password: ")
DOBCreate = input("Please enter your date of birth [DD.MM.YYYY]: ")
FavouriteArtistCreate = input("Please enter your favourite Arist: ")
FavouriteGenreCreate = input("Please enter your favourite Genre: ")
c.execute("INSERT INTO Users VALUES (AUTOINCREMENT, '{0}', '{1}', '{2}', '{3}', '{4}', '{5}')".format(NameCreate, DOBCreate, UserNameCreate, PasswordCreate, FavouriteArtistCreate, FavouriteGenreCreate))
conn.commit()
It's not enough to show your operations on the database. You need to show your database schema.
We start with two pieces of warning from sqlite doc:
The AUTOINCREMENT keyword imposes extra CPU, memory, disk space, and disk I/O overhead and should be avoided if not strictly needed. It is usually not needed.
In SQLite, a column with type INTEGER PRIMARY KEY is an alias for the ROWID (except in WITHOUT ROWID tables) which is always a 64-bit signed integer.
With that out of the way, the problem with your code is that autoincrement is specified at table creation time, not insertion time.
See a minimal example:
import sqlite3
conn = sqlite3.connect(':memory:')
c = conn.cursor()
c.execute("CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)")
NameCreate = 'a'
c.execute("INSERT INTO users ('name') VALUES (?)", (NameCreate, ))
conn.commit()
print(c.execute('select * from users').fetchall())
NameCreate = 'b'
c.execute("INSERT INTO users ('name') VALUES (?)", (NameCreate, ))
conn.commit()
print(c.execute('select * from users').fetchall())
note the CREATE TABLE line with AUTOINCREMENT, although it's not necessary as sqlite3 will do AUTOINCREMENT on any INTEGER PRIMARY KEY.
So you will need to migrate your database to a new schema with that in your table.
A bad manual solution without migration can go as follows (only for stopgap!), in the above example:
c.execute("INSERT INTO users ('id', 'name') VALUES ((SELECT MAX(id) + 1 FROM users), ?)", (NameCreate, ))
I have been working on this function in python. I intend for it to iterate over a list of phone numbers, checking with a database to see whether the number has been used yet or not. If it has been used, it should remove the phone number from the list and choose another and check the new one until an unused one has been found and return the unused one. If it has not been used, it should simply just return the number. However, after one run, it picks a number, checks it, runs, and then enters it into the database. The next run deletes the previously used number, and picks another that hasn't been used. It continues to run and enters this number into the database. The third run does not delete the previously used number from the list, but it still picks a new one regardless. Although this still works, when the numbers run out, since there are no others to pick, it continues using the last number in the list for every following run of the script. Sorry if the code is a bit sloppy right now, I am in a bit of a rush and this is only a script I have been messing around with. I hope this is clear, and not too confusing. If I need to clear any confusion, I will be glad too.
Edit: Sorry, I forgot to mention that these phone numbers are constantly grabbed from a website by another script. These set of numbers listed below is just a dummy set for testing. So in the end, I am needing to see if these recently grabbed numbers have been used by checking with the database tables.
import random
import names
##############################Information Variables##################################
emailAddress = "Fakeemail#mail.com"
titleValues = [0,1] #0 is 'Mr.', 1 is 'Mrs.'
country = 'Schwifty'
title = random.choice(titleValues)
#Generate a random name based on gender
if title == 1:
firstName = names.get_first_name(gender= 'female')
else:
firstName = names.get_first_name(gender= 'male')
lastName = names.get_last_name()
fullName = firstName + ' ' + lastName
print(fullName)
phoneNumber = '111-222-3333'
#########################################################
import sqlite3
import time
import datetime
conn = sqlite3.connect('accounts.db')
c = conn.cursor()
def createTable():
c.execute('CREATE TABLE IF NOT EXISTS accounts(Email TEXT, Name TEXT, Title TEXT, PhoneNumber TEXT, Country TEXT, DateStamp TEXT)')
def dynamic_data_entry(email, name, title, phone, country):
unix = time.time()
date = str(datetime.datetime.fromtimestamp (unix).strftime('%Y-%m-%d %H:%M:%S'))
c.execute('INSERT INTO accounts (Email, Name, Title, PhoneNumber, Country, DateStamp) VALUES (?, ?, ?, ?, ?, ?)', (email, name, title, phone, country, date))
conn.commit()
createTable()
#################################TEST NUMBER CHECK###########################
phoneNumbers = ['111-222-3333', '444-555-6666', '777-888-9999', '123-456-7890', '321-321-321']
def checkNumber(a):
c.execute("SELECT * FROM accounts WHERE PhoneNumber = ?", (a,))
row = c.fetchall()
if row:
print("Phone number has already been used, choosing another and deleting current from list.")
phoneNumbers.remove(a)
a = random.choice(phoneNumbers)
checkNumber(a)
elif row == False:
print("Number is fresh and new, using " + a)
return a
elif row == None:
print('No new phone numbers to use, exiting... ')
exit()
# for num in phoneNumbers:
# checkNumber(num)
# print(num)
checkNumber(phoneNumber)
print(phoneNumbers)
print('working')
##########################################
# INSERT DATA TO DB #
##########################################
#Insert information to database in this order: email, name, title, phone, country
dynamic_data_entry(emailAddress, fullName, title, phoneNumber, country)
conn.commit()
c.close()
conn.close()
Don’t do this. Populate a table with your phone numbers and update each phone number record with a field like ‘used’ once used.
Always keep state and data modeling in the database where possible. It is made for it.
Update in response to OP:
Create a separate table for phone numbers and replace your number field in the accounts table with a foreign key id to the primary key of the phone number table. This is called maintaining an object model or data model, so that if you want to query accounts, you have the data you need via foreign key, and if you just want phone numbers you can query the phone numbers table directly.
This way your phone number ‘objects’ can have their own attributes like ‘already called’ or ‘on do not call list’ without muddying up your accounts ‘object’.
If you want to insert a new account, you should first insert your new phone number 'object' into the phone number table and return the id, and then use that in your account insert.