Python SQLite3 function not printing any data - python

I have created a function that is supposed to send all the items, with a stock level of less than 10, in my database to a text file. But i am not receiving any data when I press the reorder button.
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()
def reorder():
global items
Database()
cursor.execute("SELECT `product_name` FROM `product` WHERE `product_qty` <= 10")
items = cursor.fetchall()
print(items)
cursor.close()
conn.close()
I expect the output to be an array of items within my database e.g. [44, 'motherboard', 9, 80] where 44 is product_id, motherboard is product_name, 9 is product_stock and 80 is product_price. I am actually getting an array with nothing in like: []

product_qty is defined as a TEXT column, so comparisons like <= will be performed between the string values of operands. This may not give the results that you expect:
>>> '8' < '10'
False
Recreate your tables with INTEGER or REAL as the column type for numeric values to get the behaviour that you want. For example:
cursor.execute("""CREATE TABLE IF NOT EXISTS `product` """
"""(product_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"""
"""product_name TEXT, product_qty INTEGER, product_price REAL)""")

Related

Python SQLite3, table not showing updates

I am trying to create a database with SQLite3 in Python.
Creating a table appears to work, but whenever I try to insert data, it doesn't seem to add anything to the database as fetchall() returns nothing, However, if I try to create the ID again, it complains about
unique constraint failed.
Initialization:
import sqlite3
conn = sqlite3.connect('login.db')
c = conn.cursor()
Table Creation:
c.execute("""CREATE TABLE Login (ID INTEGER PRIMARY KEY,
First TEXT NOT NULL,
Last TEXT NOT NULL,
Middle TEXT NOT NULL,
Gender TEXT NOT NULL);""")
conn.commit()
Data Insert:
c.execute("""INSERT INTO Login VALUES (6, 'First', 'Last', 'Hello', 'Male');""")
conn.commit()
Fetching Tables:
print(c.fetchall())
c.close()
conn.close()
When dropping the table into an online reader, it also appears empty.
EDIT:
This is what is shown in the db reader, and in google sheets,
large list of blanks / ";" then this
c.fetchall() would return all of the rows from a SELECT query, which you aren't doing.
import sqlite3
conn = sqlite3.connect('login.db')
c = conn.cursor()
c.execute("""CREATE TABLE Login (ID INTEGER PRIMARY KEY, First TEXT NOT NULL, Last TEXT NOT NULL, Middle TEXT NOT NULL, Gender TEXT NOT NULL);""")
conn.commit()
c.execute("""INSERT INTO Login VALUES (6, 'First', 'Last', 'Hello', 'Male');""")
conn.commit()
c.execute("SELECT * FROM login")
print(c.fetchall())
will happily print
[(6, 'First', 'Last', 'Hello', 'Male')]
As an aside, your code is vulnerable to SQL injection attacks, and you should do
import sqlite3
conn = sqlite3.connect("login.db")
c = conn.cursor()
c.execute(
"""CREATE TABLE Login (ID INTEGER PRIMARY KEY, First TEXT NOT NULL, Last TEXT NOT NULL, Middle TEXT NOT NULL, Gender TEXT NOT NULL);"""
)
conn.commit()
c.execute(
"INSERT INTO Login (ID, First, Last, Middle, Gender) VALUES (?,?,?,?,?)",
(6, "First", "Last", "Hello", "Male"),
)
conn.commit()
c.execute("SELECT * FROM login")
print(c.fetchall())

sqlite3.IntegrityError: Datatype Missmatch

When I run my code, i am getting an error saying "sqlite3.IntegrityError: Datatype Mismatch". I believe it's something to do with database but I can't seem to find the error. I checked if i have let a foreign key of a particular datatype reference an attribute of a different datatype but still can't find the error. Here is my database:
import sqlite3
connection = sqlite3.connect('database.db')
cursor = connection.cursor()
cursor.execute("""CREATE TABLE IF NOT EXISTS tblCustomer (
customerID TEXT (6),
firstName TEXT (10),
secondName TEXT (15),
dob DATE,
address TEXT,
telephone INT (11),
primary key (customerID)
)""")
tblCustomer = []
cursor.execute("""CREATE TABLE IF NOT EXISTS tblEmployee (
employeeID TEXT (6),
firstName TEXT (10),
secondName TEXT (15),
dob DATE,
address TEXT,
telephone INT (11),
gender TEXT,
role TEXT,
salary INT,
primary key (employeeID)
)""")
tblEmployee = []
cursor.execute("""CREATE TABLE IF NOT EXISTS tblBooking (
bookingID TEXT (6),
checkInDate DATE,
checkOutDate DATE,
numberOfOccupants INT,
customerID TEXT,
roomID TEXT,
primary key (bookingID),
foreign key (customerID) REFERENCES tblCustomer(customerID),
foreign key (roomID) REFERENCES tblRoomAllocation(roomID)
)""")
tblBooking = []
cursor.execute("""CREATE TABLE IF NOT EXISTS tblRoomAllocation (
roomID TEXT (6),
roomType TEXT (20),
DateAdded DATE,
DateVacated DATE,
housekeepingID TEXT,
primary key (roomID),
foreign key (housekeepingID) REFERENCES tblHousekeeping(housekeepingID)
)""")
tblRoomAllocation = []
cursor.execute("""CREATE TABLE IF NOT EXISTS tblHousekeeping (
housekeepingID TEXT (6),
dob DATE,
assignedTo TEXT (20),
primary key (housekeepingID)
)""")
tblHousekeeping = []
cursor.execute("""CREATE TABLE IF NOT EXISTS tblPayment (
paymentID TEXT (6),
dob DATE,
amountPaid CURRENCY,
customerID TEXT (6),
primary key (paymentID),
foreign key (customerID) REFERENCES tblCustomer(customerID)
)""")
tblPayment = []
cursor.execute("""CREATE TABLE IF NOT EXISTS tblOrder(
orderID TEXT (6),
price CURRENCY,
customerID TEXT (6),
treatmentID TEXT (6),
primary key (orderID),
foreign key (customerID) REFERENCES tblCustomer(customerID),
foreign key (treatmentID) REFERENCES tblTreatment(treatmentID)
)""")
tblOrder = []
cursor.execute("""CREATE TABLE IF NOT EXISTS tblTreatment(
treatmentID TEXT (6),
treatmentType TEXT (20),
extras TEXT(20),
employeeID TEXT (6),
primary key (treatmentID),
foreign key (employeeID) REFERENCES tblEmployee(employeeID)
)""")
tblTreatment = []
cursor.execute("""CREATE TABLE IF NOT EXISTS tblUser (
userID TEXT (6),
firstName TEXT (10),
secondName TEXT (15),
username VARCHAR(20),
password VARCHAR (20),
primary key (userID)
)""")
tblUser = []
SQLite does not support DATE data type.
See what is supported:
https://www.sqlite.org/datatype3.html
Try using an INTEGER (store unix timestamp), or a TEXT (for iso8601 date).

How can I print schema / table definitions in SQLAlchemy

How can I print out the schema of all tables using sqlalchemy?
This is how I do it using SQLite3: I run an SQL to print out the schema of all tables in the database:
import sqlite3
conn = sqlite3.connect("example.db")
cur = conn.cursor()
rs = cur.execute(
"""
SELECT name, sql FROM sqlite_master
WHERE type='table'
ORDER BY name;
""")
for name, schema, *args in rs:
print(name)
print(schema)
print()
With output that can look like this:
albums
CREATE TABLE "albums"
(
[AlbumId] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[Title] NVARCHAR(160) NOT NULL,
[ArtistId] INTEGER NOT NULL,
FOREIGN KEY ([ArtistId]) REFERENCES "artists" ([ArtistId])
ON DELETE NO ACTION ON UPDATE NO ACTION
)
artists
CREATE TABLE "artists"
(
[ArtistId] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[Name] NVARCHAR(120)
)
Is there a way to do it with pure sqlalchemy api calls, something better than this?
metadata = sqlalchemy.MetaData()
metadata.reflect(engine)
insp = sqlalchemy.inspect(engine)
for table_name in metadata.tables:
print(table_name)
for column in insp.get_columns(table_name):
for name,value in column.items():
print(' ', end='')
if value:
field = name if value in [True, 'auto'] else value
print(field, end=' ')
print()
Output:
albums
AlbumId INTEGER autoincrement primary_key
Title NVARCHAR(160) autoincrement
ArtistId INTEGER autoincrement
artists
ArtistId INTEGER autoincrement primary_key
Name NVARCHAR(120) nullable autoincrement
This bit in the SQLAlchemy docs may help: they suggest doing this:
def dump(sql, *multiparams, **params):
print(sql.compile(dialect=engine.dialect))
engine = create_engine('postgresql://', strategy='mock', executor=dump)
metadata.create_all(engine, checkfirst=False)

Sqlite 3 multiple foreign keys

I'm working on my A2 coursework and I've run into a problem with multiple foreign keys. Here is all code I think is relevant, if you need more please reply saying so.
In TeacherInfo:
def TMenu():
print()
MenuPupil = menuClass.Menu("Teacher")
MenuPupil.printMenu()
Choice = int(input("Enter your choice: "))
if Choice == 1:
db_name = "PupilPremiumTableNew.db"
sql= """Create table TeacherInfo
(TeacherID int,
TeacherInitials text,
TeacherYearTeaching int,
primary key(TeacherID))"""
CreateTeachersTable(db_name, "TeacherInfo",sql)
In PupilPremiumTableNew:
db_name = "PupilPremiumTableNew.db"
sql= """Create table PupilPremiumTableNew
(PupilID int,
WritingGrade text,
ReadingGrade text,
MathsGrade text,
Term text,
RecordID int,
InterventionsReading text,
InterventionsWriting text,
InterventionsMaths text,
primary key(RecordID),
foreign key(PupilID)
references PupilInfo(PupilID)
foreign key(TeacherID)
references TeacherInfo (TeacherID)
on update cascade on delete cascade)"""
CreatePupilPremiumTable(db_name, "PupilPremiumTableNew",sql)
def CreateTeachersTable(db_name,table_name,sql):
with sqlite3.connect(db_name) as db:
cursor = db.cursor()
cursor.execute("select name from sqlite_master where name =?",(table_name,))
result = cursor.fetchall()
keep_table = True
if len(result) == 1:
response = input("The table {0} already exists, do you wish to recreate it?(y/n): ".format(table_name))
if response == 'y':
keep_table = False
print("The table {0} has been recreated, all existing data has been deleted. ".format(table_name))
cursor.execute("drop table if exists {0}".format(table_name))
db.commit()
else:
print("Existing table was kept. ")
else:
keep_table = False
if not keep_table:
cursor.execute(sql)
db.commit()
The error I get says: sqlite3.OperationalError: unknown column "TeacherID" in foreign key definition
As you may notice a foreign key from another file, PupilTable is in there. At the moment that one works, if I remove TeacherID as a foreign key it all works
Thanks
Devilb77
I forgot to tell it what TeacherID was, so to fix the issue I added TeacherID int, into the variable sql
Here is what it now looks like:
db_name = "PupilPremiumTableNew.db"
sql= """Create table PupilPremiumTableNew
(PupilID int,
WritingGrade text,
ReadingGrade text,
MathsGrade text,
Term text,
RecordID int,
InterventionsReading text,
InterventionsWriting text,
InterventionsMaths text,
TeacherID int,
primary key(RecordID),
foreign key(PupilID)
references PupilInfo(PupilID)
foreign key(TeacherID)
references TeacherInfo (TeacherID)
on update cascade on delete cascade)"""
CreatePupilPremiumTable(db_name, "PupilPremiumTableNew",sql)

How to create unique rows in a table?

I`m just started to learn SQLite. I use python.
The question is how to create rows in tables, so that they are uniqe by name and how to use (extract) id1 and id2 to insert them into a separate table.
import sqlite3
conn = sqlite3.connect('my.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS table1(
id1 integer primary key autoincrement, name)''')
c.execute('''CREATE TABLE IF NOT EXISTS table2(
id2 integer primary key autoincrement, name)''')
c.execute('CREATE TABLE IF NOT EXISTS t1_t2(id1, id2)') # many-to-many
conn.commit()
conn.close()
conn = sqlite3.connect('my.db')
c = conn.cursor()
c.execute('INSERT INTO table1 VALUES (null, "Sue Monk Kidd")')
c.execute('INSERT INTO table2 VALUES (null, "The Invention of Wings")')
#c.execute('INSERT INTO t1_t2 VALUES (id1, id2)')
c.execute('INSERT INTO table1 VALUES (null, "Colleen Hoover")')
c.execute('INSERT INTO table2 VALUES (null, "Maybe Someday")')
#c.execute('INSERT INTO t1_t2 VALUES (id1, id2)')
Thanks.
I think you have some problems with the table creation. I doubt that it worked, because the name columns don't have a type. They should probably be varchar of some length. The JOIN table definition isn't right, either.
CREATE TABLE IF NOT EXISTS table1 (
id1 integer primary key autoincrement,
name varchar(80)
);
CREATE TABLE IF NOT EXISTS table2 (
id2 integer primary key autoincrement,
name varchar(80)
);
CREATE TABLE IF NOT EXISTS t1_t2 (
id1 integer,
id2 integer,
primary key(id1, id2),
foreign key(id1) references table1(id1),
foreign key(id2) references table2(id2)
);
I would not create the tables in code. Script them, execute in the SQLite admin, and have the tables ready to go when your Python app runs.
I would think much harder about your table names if these are more than examples.
I found the problem of unique names on unique column problem.
Actually, I should change INSERT to INSERT OR IGNORE
import sqlite3
conn = sqlite3.connect('my.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS table1(
id1 integer primary key autoincrement, name TEXT unique)''')
c.execute('''CREATE TABLE IF NOT EXISTS table2(
id2 integer primary key autoincrement, name TEXT unique)''')
c.execute('CREATE TABLE IF NOT EXISTS t1_t2(id1, id2)') # many-to-many
conn.commit()
conn.close()
conn = sqlite3.connect('my.db')
c = conn.cursor()
c.execute('INSERT OR IGNORE INTO table1 VALUES (null, "Sue Monk Kidd")')
c.execute('INSERT OR IGNORE INTO table2 VALUES (null, "The Invention of Wings")')

Categories

Resources