PRAGMA foreign key error (Python) - python

Going to paste in the entire file because I have absolutely no idea how to fix my issue;
import sqlite3
import time
import datetime
import sys
conn = sqlite3.connect('offerdatabase1.db')
c = conn.cursor()
c.execute('PRAGMA foreign_keys = ON')
############################# Creating the Database Tables #############################
# Creating the 'Odds' Table
def create_odds_table():
c.execute("""CREATE TABLE IF NOT EXISTS Odds(OddsID INTEGER PRIMARY KEY,
TeamSelection TEXT,
BackOdds INTEGER,
LayOdds INTEGER)
""")
c.execute('PRAGMA foreign_keys = ON')
# # # Creating the 'Value' Table # # #
def create_value_table():
c.execute("""CREATE TABLE IF NOT EXISTS Value(ValueID INTEGER PRIMARY KEY,
BackStake INTEGER,
LayStake INTEGER,
Liability INTEGER,
NetValue INTEGER)
""")
c.execute('PRAGMA foreign_keys = ON')
# Creating the 'User' Table
def create_user_table():
c.execute("""CREATE TABLE IF NOT EXISTS User(UserID INTEGER PRIMARY KEY,
FirstName TEXT,
LastName TEXT,
Email TEXT,
Date TEXT,
Time TEXT)
""")
c.execute('PRAGMA foreign_keys = ON')
# Creating the 'Offer' Table
def create_offer_table():
c.execute("""CREATE TABLE IF NOT EXISTS Offer(OfferID INTEGER PRIMARY KEY,
OfferType TEXT,
OfferDesc TEXT,
Bookmaker TEXT,
Exchange TEXT,
OddsID INTEGER,
ValueID INTEGER,
UserID INTEGER,
FOREIGN KEY(OddsID) REFERENCES Odds(OddsID),
FOREIGN KEY(ValueID) REFERENCES Value(ValueID),
FOREIGN KEY(UserID) REFERENCES User(UserID))""")
c.execute('PRAGMA foreign_keys = ON')
# Running the Subroutines, in order to create the database with tables previously stated.
if __name__ == "__main__":
db_name = ('offerdatabase1.db')
c.execute('PRAGMA foreign_keys = ON')
create_odds_table()
create_value_table()
create_user_table()
create_offer_table()
############################# Inserting Data into Tables #############################
def data_entry_odds():
print('==================== Odds and Team Selection ====================')
TeamSelection = input('Team you selected: ')
BackOdds = input('Back Bet Odds: ')
LayOdds = input('Lay Bet Odds: ')
c.execute("INSERT INTO Odds (TeamSelection, BackOdds, LayOdds) VALUES (?, ?, ?)",
(TeamSelection, BackOdds, LayOdds))
c.execute('PRAGMA foreign_keys = ON')
conn.commit()
def data_entry_value():
print('================ Stakes, Liability and Net Value ================')
BackStake = input('Stake on Back Bet: ')
LayStake = input('Stake on Lay Bet: ')
Liability = input('Liability (applies only with exchange): ')
NetValue = input('Net value : ')
c.execute("INSERT INTO Value (BackStake, LayStake, Liability, NetValue) VALUES (?, ?, ?, ?)",
(BackStake, LayStake, Liability, NetValue))
c.execute('PRAGMA foreign_keys = ON')
conn.commit()
def data_entry_user():
print('======================== User Information =======================')
FirstName = input('Firstname: ')
LastName = input('Surname: ')
Email = input('Email Address: ')
Date = time.strftime("%d/%m/%Y")
Time = time.strftime("%H:%M")
c.execute("INSERT INTO User (FirstName, LastName, Email, Date, Time) VALUES (?, ?, ?, ?, ?)",
(FirstName, LastName, Email, Date, Time))
c.execute('PRAGMA foreign_keys = ON')
conn.commit()
def data_entry_offer():
print('======================= Offer Information =======================')
OfferType = input('Type of Offer: ')
OfferDesc = input('Offer Description: ')
Bookmaker = input('Name of Bookmaker: ')
Exchange = input('Name of Exchange: ')
c.execute("INSERT INTO Offer (OfferType, OfferDesc, Bookmaker, Exchange) VALUES (?, ?, ?, ?)",
(OfferType, OfferDesc, Bookmaker, Exchange))
c.execute('PRAGMA foreign_keys = ON')
conn.commit()
########################### Text Based User Interface ###########################
def rootchoice():
userchoice = input('Would you like to track a bet? (Y - Yes, N - No) ')
if userchoice.upper() == 'Y':
yeschoice()
elif userchoice.upper() == 'N':
nochoice()
else:
print('*ERROR* - Please enter either \'Y\' or \'N\' (no other characters accepted)')
rootchoice()
def yeschoice():
data_entry_user()
data_entry_offer()
data_entry_odds()
data_entry_value()
print('Data entry complete, recorded successfully.')
loopchoice()
def nochoice():
print('Thank you for using James\' Betting Tracker, goodbye!')
sys.exit()
def loopchoice():
loopuserchoice = input('Would you like to track another bet? (Y - Yes, N - No) ')
if loopuserchoice.upper() == 'Y':
yeschoice()
elif loopuserchoice.upper() == 'N':
nochoice
else:
print('*ERROR* - Please enter either \'Y\' or \'N\' (no other characters accepted)')
loopchoice()
print('Welcome to James\' Betting Tracker!')
rootchoice()
Excuse the annotation and ridiculous headings, I am writing this code for a school project. After reading around the subject of foreign keys within sqlite3, I stumbled across the command;
PRAGMA foreign_keys = ON
After reading around about it, I was told that you had to set PRAGMA foreign_keys to ON everytime a database connection was made.
I've done this, but the foreign keys still don't work with my database.
Any help would be greatly appreciated, i'm incredibly new to the world of python and programming in general, thanks!

Foreign key constraints are called "constraints" because they are constraints, i.e., the constrain the values in the database. In other words, they prevent you from inserting values that would violate the rules.
In this case, you would get an error if you tried to insert an invalid OddsID, ValueID or UserID number (one that does not exist in the parent table) into the Offers table.
But you never do that; you leave those columns empty.
It is not possible for the database to automatically insert a reference to a row in the parent table – which of those rows should it choose?
If your data model requires that all Offers rows have valid references to the other three tables, add NOT NULL constraints to those columns.

Related

sqlite3 | data doesn't save in table

The code works when I run it but when I run it again the data from the previous run is not saved, but the table is still there. I have tried many methods of saving the file and it still doesn't save
import sqlite3
conn = sqlite3.connect('conntact.db')
cursor = conn.cursor()
check = cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='contacts'");
if check == 0:
cursor.execute('''CREATE TABLE contacts
(ID INTEGER PRIMARY KEY AUTOINCREMENT,
NAME TEXT NOT NULL,
EMAIL TEXT NOT NULL,
PHONE TEXT NOT NULL);''');
def add_contacts():
name1 = input("Enter contact name: ")
email1 = input("Enter contact email: ")
phone1 = input("Enter contact phone number: ")
id_s = input("Enter id: ")
cursor.execute("INSERT INTO contacts (ID, NAME,EMAIL,PHONE) VALUES (?,?,?,?)", (id_s, name1, email1, phone1));
def read_all_contact():
cursor.execute("SELECT * FROM contacts");
records = cursor.fetchall()
print(f"Total rows are: {len(records)}")
for row in records:
print(f'ID: {row[0]}')
print(f'Name: {row[1]}')
print(f'Email: {row[2]}')
print(f'Phone: {row[3]}\n')
add_contacts()
read_all_contact()
conn.close()
Any help would a apreciated
Remove check = ... line, which is wrong anyway.
Remove if check == 0
Replace "CREATE TABLE contacts" with "CREATE TABLE IF NOT EXISTS contacts"
Execute conn.commit()

How to let user input TABLE name in sqlite3, python3?

I need to prompt a user to create a student table, check if a table with such a name exists in the database, and if not create it.
import sqlite3
conn = sqlite3.connect('School')
print ("Database has been created")
def create_table():
TableName = input("Enter table name: ")
tb_create ="""CREATE TABLE , (TableName,) (ID INT PRIMARY KEY,title VARCHAR(10), forename VARCHAR(20),
surname VARCHAR(20))"""
tb_exists ="SELECT name FROM sqlite_master WHERE type='table' AND name= ?", (TableName,)
if not conn.execute(tb_exists).fetchone():
conn.execute(tb_create)
print ("Table created successfully")
else:
print ("Table Exists!")
I know its possible to inser user inputed value into a table, but how do I create a table with inputed name? What should go after CREATE TABLE? If I use , (TableName,) the code wont compile.
Also, once the new table has been added to database, how do I indicate its name in INSER INTO query?
def insert_data():
conn.execute("INSERT INTO TableName (ID,title,forename,surname)VALUES \
(234,'Mr','XXX','XXX'")
conn.commit()
The correct syntax for a CREATE TABLE statement is:
CREATE TABLE tablename(column1 datatype1, column2 datatype2, ....)
Since you want the user to provide the name of the table, you can do it with string interpolation, because you can't pass it with a ? placeholder in the sql query as aparameter:
tb_create = f"CREATE TABLE [{TableName}](ID INTEGER PRIMARY KEY, title TEXT, forename TEXT, surname TEXT)"
The table's name must be enclosed inside square brackets, just in case the user provided a name that is not valid (for example it starts with digit or contains spaces).
Also, if you want the column ID to be autoincrement, you must use INTEGER instead of INT for its data type.
Also, there is no VARCHAR data type in SQLite. Use TEXT.
You can define the variable TableName as global so that you can use it in all the functions, like insert_data().
Use string interpolation for the INSERT statement also.
import sqlite3
conn = sqlite3.connect("School")
print ("Database has been created")
TableName = ""
def create_table():
global TableName
TableName = input("Enter table name: ").strip()
tb_exists ="SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?"
if not conn.execute(tb_exists, (TableName,)).fetchone():
tb_create = f"CREATE TABLE [{TableName}](ID INTEGER PRIMARY KEY, title TEXT, forename TEXT, surname TEXT)"
conn.execute(tb_create)
print("Table created successfully")
else:
print("Table Exists!")
def insert_data():
if len(TableName) > 0:
conn.execute(f"INSERT INTO [{TableName}] (ID,title,forename,surname) VALUES (234,'Mr','XXX','XXX')")
conn.commit()
create_table()
insert_data()
The name of the table, or of the columns cannot be parameterized, so you must build the query string. It means that you should control that the entered name is sane because building query from strings is know to be a vector for SQL injection.
But most (if not all) SQL database allow to create a table if it does not already exists. The syntax is just:
CREATE TABLE table_name IF NOT EXISTS (
column_name type,
...)
So here, you could just do:
import re
...
def create_table():
TableName = input("Enter table name: ")
# control name:
if not re.match(r'\w*$', TableName):
raise IllegalValue("Invalid table name")
tb_create =f"""CREATE TABLE {TableName} IF NOT EXISTS (ID INT PRIMARY KEY,title VARCHAR(10),
forename VARCHAR(20), surname VARCHAR(20))"""
conn.execute(tb_create)

Why do I get the error no such column name

I'm writing a program to store credit card values as practice.
I keep getting the error "sqlite3.OperationalError: no such column:
the table is created and the column: name.
the column name exists in in the cards table in cc.db in SQLiteStudio
any help appreciated.
import sqlite3
conn = sqlite3.connect('cc.db')
c = conn.cursor()
def createTABLE():
c.execute("""CREATE TABLE IF NOT EXISTS cards (
name text,
ccnumber integer,
exp_date text,
csv integer
)""")
conn.commit()
print('table created')
def entercard():
ccname = input('Enter the name of the new card: ')
ccnumber = input('Enter the card number: ')
ccexp_date = input('Enter the Expiration date: ')
cccsv = input('Enter the CSV number from the back of the card: ')
c.execute("INSERT INTO cards VALUES (?, ?, ?, ?),(name, ccnumber, exp_date, csv)");
conn.commit()
def printall():
for card in c.execute('SELECT * FROM cards'):
print(card)
createTABLE()
entercard()
printall()
conn.close()
I cannot determine why you're getting that particular error, but you have a problem with the following line:
c.execute("INSERT INTO cards VALUES (?, ?, ?, ?),(name, ccnumber, exp_date, csv)");
It is all a string. You need instead to separate the variables from the query string like so:
c.execute("INSERT INTO cards VALUES (?, ?, ?, ?)",(name, ccnumber, exp_date, csv))
I did the bellow in order to store values and retrieve them from the table.
You need to make the line look more like this.
c.execute("INSERT INTO cards(name,ccnumber,exp_date,csv) VALUES ('Tom','new1','new2','new3');")
Space
import sqlite3
conn = sqlite3.connect('cc.db')
c = conn.cursor()
def createTABLE():
c.execute("""CREATE TABLE IF NOT EXISTS cards (
name text,
ccnumber integer,
exp_date text,
csv integer)""")
conn.commit()
c.execute("INSERT INTO cards(name) VALUES ('Tom');")
conn.commit()
p=c.execute('SELECT * FROM cards')
j= p.fetchall()
print(j)
for i in j:
print(i)
print(p)
print('table created')
def entercard():
ccname = input('Enter the name of the new card: ')
c.execute("INSERT INTO cards(name) VALUES ('"+ccname+"')")
conn.commit()
def printall():
for card in c.execute('SELECT * FROM cards'):
print(card)
createTABLE()
entercard()
printall()
conn.close()

Copy data from one table to another sqlite3

So I have a database containing the products I will be holding, within this database I have a basket table where users can add items they would like to buy. For some reason, I am unable to take a selection within the view window and copy that data into my basket table.
Here is the function I have created for moving the data.
def Move():
if not tree.selection():
error = tkMessageBox.showerror("Error", "Cannot move nothing to basket")
else:
result = tkMessageBox.askquestion('CCOS', 'Do you want to add this to the basket?', icon="warning")
if result == 'yes':
curItem = tree.selection()
print(curItem)
contents = (tree.item(curItem))
selecteditem = contents['values']
Database()
cursor.execute("INSERT INTO `basket` (product_name, product_qty, product_price) VALUES(?, ?, ?)",
(str(PRODUCT_NAME.get()), int(PRODUCT_QTY.get()), int(PRODUCT_PRICE.get())))
conn.commit()
PRODUCT_ID.set("")
PRODUCT_NAME.set("")
PRODUCT_PRICE.set("")
PRODUCT_QTY.set("")
cursor.close()
conn.close()
Comment:
I have a range of different functions in my code, Database() is its own function that creates the database and cursor = conn.connect(). I am not getting an error, but when i run the function, no data is copied into the table.
When I call print(curItem), all that is outputted is : ('I002',)
Here is the database function:
def Database():
global conn, cursor
conn = sqlite3.connect("main_storage.db")
cursor = conn.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS `admin` (admin_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, username TEXT, password TEXT)")
cursor.execute("CREATE TABLE IF NOT EXISTS `product` (product_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, product_name TEXT, product_qty TEXT, product_price TEXT)")
cursor.execute("CREATE TABLE IF NOT EXISTS `basket` (product_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, product_name TEXT, product_qty TEXT, product_price TEXT)")
cursor.execute("SELECT * FROM `admin` WHERE `username` = 'admin' AND `password` = 'admin'")
if cursor.fetchone() is None:
cursor.execute("INSERT INTO `admin` (username, password) VALUES('admin', 'admin')")
conn.commit()

Can't get the last row id from SQLITE3 database

I have a script that asks for input, and that input is then inserted into a table.
The next time the script is run, I'd like for it to tell the user what id the last input has.
The table looks like: id INTEGER PRIMARY KEY AUTOINCREMENT, userid TEXT, domain TEXT, password TEXT, webserver TEXT, sqlserver TEXT
I was told I could use SELECT seq from SQLITE_SEQUENCE WHERE name='table_name' but it yields the following text: instead of the id from the last row.
Please note that I'm an extremely new Python / SQLite3 coder!
For your reference, the code sofar looks like this:
#!/usr/bin/python
import os, sys, sqlite3
######## CHECK SYSTEM COMPATIBILITY ########
if os.name =='posix':
os.system("clear")#CLEAR SCREEN#
pass
else:
sys.exit("Operating System is not supported")
######## END CHECK SYSTEM COMPATIBILITY ########
######## CHECK IF SCRIPT IS RUN AS ROOT ########
#if os.geteuid() != 0:
# sys.exit("Script must be run as root")
#else:
# pass
####### END CHECK IF SCRIPT IS RUN AS ROOT ########
####### CREATE DATABASE AND CHECK IF TABLE EXISTS ##########
conn = sqlite3.connect("dat.db")
c = conn.cursor()
c.execute ('''CREATE TABLE IF NOT EXISTS kunder
(id INTEGER PRIMARY KEY AUTOINCREMENT, userid TEXT, domain TEXT, password TEXT, webserver TEXT, sqlserver TEXT)''')
conn.commit()
print c.execute ("SELECT seq from SQLITE_SEQUENCE WHERE name='kunder'")
conn.close()
######## DONE CREATE DATABASE AND CHECK IF TABLE EXISTS #########
###### ASK FOR INPUT ##########
########### HERE NEEDS TO BE A CHECK TO DETERMINE THE LATEST USERID - ALSO NEEDS TO BE FOR WEBSERVER AND PASSWORD #################
userid = raw_input("Enter userid: ")
########### HERE NEEDS TO BE A CHECK TO SEE IF USERID EXISTS!!!!!#####################
domain = raw_input("Enter domain: ")
password = raw_input("Enter password: ")
########### NEEDS TO BE A WAY TO AUTOGENERATE A PASSWORD!!! ####################
webserver = raw_input("Enter webserver: ")
sqlserver = raw_input("Enter sqlserver: ")
###### FINISHED ASK FOR INPUT #######
######## DATABASE ###########
conn = sqlite3.connect("dat.db")
c = conn.cursor()
c.execute ("INSERT INTO kunder (userid, domain, password, webserver, sqlserver) VALUES (?,?,?,?,?)", (userid, domain, password, webserver, sqlserver))
conn.commit()
conn.close()
####### DONE WITH DATABASE ##########
The SQL statement SELECT max(id) FROM table_name should give you the maximum id. If you're auto-incrementing then this would be the same as the last inserted.
Edit: To get the actual value in python means reading it from the cursor:
cursor = sqlite3.execute('SELECT max(id) FROM table_name')
max_id = cursor.fetchone()[0]
fetchone() returns the first row from the select statement as a tuple (unless a row_factory is used), so fetchone()[0] will, in this case, return the first (and only) column in the first (and only) row, i.e. the max(id).
See http://docs.python.org/2/library/sqlite3.html for more info.
Try using sqlite3_last_insert_rowid()
import sqlite3
data_person_name = [('Michael', 'Fox'),
('Adam', 'Miller'),
('Andrew', 'Peck'),
('James', 'Shroyer'),
('Eric', 'Burger')]
con = sqlite3.connect(":memory:")
c = con.cursor()
c.execute('''CREATE TABLE q1_person_name
(name_id INTEGER PRIMARY KEY,
first_name varchar(20) NOT NULL,
last_name varchar(20) NOT NULL)''')
for data_person in data_person_name:
c.execute('INSERT INTO q1_person_name(first_name, last_name) VALUES (?,?)', data_person)
# get the last rowid inserted
last_name_id = c.lastrowid
print(last_name_id)

Categories