SQLite not saving data between uses - python

I made a module with the following contents:
import sqlite3 as sq
connection = sq.connect("test.db")
cursor = connection.cursor()
cursor.execute("DROP TABLE IF EXISTS test")
cursor.execute("CREATE TABLE test (st TEXT)")
cursor.execute("INSERT INTO test VALUES ('testing')")
cursor.execute("SELECT * FROM test")
print(cursor.fetchall())
cursor.close()
connection.close()
connection2 = sq.connect("test.db")
cursor2 = connection2.cursor()
cursor2.execute("SELECT * FROM test")
print(cursor2.fetchall())
But when I ran it, it printed the following:
[('testing',)]
[]
It should have printed:
[('testing',)]
[('testing',)]
What is wrong?

You did not commit your changes into the DB. When you discard the connection, the transaction will be rolled back. This works
import sqlite3 as sq
connection = sq.connect("test.db")
cursor = connection.cursor()
cursor.execute("DROP TABLE IF EXISTS test")
cursor.execute("CREATE TABLE test (st TEXT)")
cursor.execute("INSERT INTO test VALUES ('testing')")
connection.commit() # !!!
cursor.execute("SELECT * FROM test")
print(cursor.fetchall())
cursor.close()
connection.close() # rolls back changes without .commit()
connection2 = sq.connect("test.db")
cursor2 = connection2.cursor()
cursor2.execute("SELECT * FROM test")
print(cursor2.fetchall())

Related

My Sqlite python code won't delete a record from a table [duplicate]

I made a module with the following contents:
import sqlite3 as sq
connection = sq.connect("test.db")
cursor = connection.cursor()
cursor.execute("DROP TABLE IF EXISTS test")
cursor.execute("CREATE TABLE test (st TEXT)")
cursor.execute("INSERT INTO test VALUES ('testing')")
cursor.execute("SELECT * FROM test")
print(cursor.fetchall())
cursor.close()
connection.close()
connection2 = sq.connect("test.db")
cursor2 = connection2.cursor()
cursor2.execute("SELECT * FROM test")
print(cursor2.fetchall())
But when I ran it, it printed the following:
[('testing',)]
[]
It should have printed:
[('testing',)]
[('testing',)]
What is wrong?
You did not commit your changes into the DB. When you discard the connection, the transaction will be rolled back. This works
import sqlite3 as sq
connection = sq.connect("test.db")
cursor = connection.cursor()
cursor.execute("DROP TABLE IF EXISTS test")
cursor.execute("CREATE TABLE test (st TEXT)")
cursor.execute("INSERT INTO test VALUES ('testing')")
connection.commit() # !!!
cursor.execute("SELECT * FROM test")
print(cursor.fetchall())
cursor.close()
connection.close() # rolls back changes without .commit()
connection2 = sq.connect("test.db")
cursor2 = connection2.cursor()
cursor2.execute("SELECT * FROM test")
print(cursor2.fetchall())

Basic Database made with SQLITE3

I created a basic database in python with sqlite3 which takes in 3 values and stores them. Now where the problem lies is that when I created a function that is supposed to output the values, no syntax errors were displayed on terminal and none of my values were printed. Im guessing this is a minor error but I am not able to spot it.
The code is given below:
import sqlite3
def create_table():
conn = sqlite3.connect("lite.db")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS store (item TEXT, quantity
INTEGER, price FLOAT)")
conn.commit()
conn.close()
def insert(item, quantity, price):
conn = sqlite3.connect("lite.db")
cur = conn.cursor()
cur.execute("INSERT INTO store VALUES ('?, ?, ?')", (item, quantity,
price))
conn.commit()
conn.close()
insert("Mug", 8, 6)
def view():
conn = sqlite3.connect("lite.db")
cur = conn.cursor()
cur.execute("SELECT * FROM store")
rows = cur.fetchall()
conn.close()
return rows
print(view())
Again no error messages were displayed but my values are not displayed.
I have tried it. it seems the single quotes are not needed in the insert. See modified below:
import sqlite3
def create_table():
conn = sqlite3.connect("lite.db")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS store (item TEXT, quantity INTEGER, price FLOAT)")
conn.commit()
conn.close()
def insert(item, quantity, price):
conn = sqlite3.connect("lite.db")
cur = conn.cursor()
cur.execute("INSERT INTO store VALUES (?,?,?)", (item, quantity, price))
conn.commit()
conn.close()
def view():
conn = sqlite3.connect("lite.db")
cur = conn.cursor()
cur.execute("SELECT * FROM store")
rows = cur.fetchall()
conn.close()
return rows
create_table()
insert("Mug", 1, 5)
print(view())

Correct approach to test drop table sqlite in unittest

I'm writing unit tests to test my environment.
I have created tests such as:
def test_database_file_present_and_readable(self):
self.assertTrue(os.access(path_db_file, os.R_OK))
def test_connect_to_db(self):
conn = sqlite3.connect(path_db_file)
conn.close()
def test_create_table(self):
conn = sqlite3.connect(path_db_file)
cur = conn.cursor()
cur.execute("CREATE TABLE test_table (id integer PRIMARY KEY, name text)")
conn.commit()
conn.close()
def test_insert_into_table(self):
conn = sqlite3.connect(path_db_file)
cur = conn.cursor()
cur.execute("insert into test_table (name) values (?)", ["Test value"])
conn.commit()
conn.close()
def test_update_table(self):
conn = sqlite3.connect(path_db_file)
cur = conn.cursor()
cur.execute("update test_table set id = 2 where id = ?", [1])
conn.commit()
conn.close()
def test_delete_from_table(self):
conn = sqlite3.connect(path_db_file)
cur = conn.cursor()
cur.execute("delete from test_table where id = ?", [2])
conn.commit()
conn.close()
def test_if_test_table_is_empty(self):
conn = sqlite3.connect(path_db_file)
cur = conn.cursor()
result = cur.execute("select exists(select 1 from test_table)").fetchall()
conn.commit()
conn.close()
self.assertTrue(result == 1)
def test_delete_table(self):
conn = sqlite3.connect(path_db_file)
cur = conn.cursor()
cur.execute("drop table test_table")
conn.commit()
conn.close()
And during program execution order of tests is unknown - how to set the order or how to clean up database after creating tests with table creation?
You can get pointers about test method execution order here: Python unittest.TestCase execution order
One suggestion - if you are going for such testing, it's better to mock external dependencies like sqlite & test only the code you've written.

sqlite transaction doesn't commit

I run this code but it doesn't commit anything.
def them_mon(self):
ten_mon = ['Tin học', 'Toán', 'Nhạc', 'Mỹ thuật', 'Sinh', 'Lý', 'Văn', 'Thể dục', 'Sử', 'Địa', 'GDCD', 'TTH', 'AVTH', 'KHKT']
len_tm = len(ten_mon)
i = 0
while i < len_tm:
ten = ten_mon[i]
#print(ten)
sql = "INSERT INTO bang_diem(TEN_MON) VALUES(?)"
self.conn.execute(sql, (ten,))
i+=1
self.conn.commit()
No record is added or anything in bang_diem
You have to execute with cursor object and not the connection object
# Creates or opens a DB
db = sqlite3.connect('data.db')
# Get a cursor object
cursor = db.cursor()
cursor.execute("INSERT INTO tabe_name (column1, column2) VALUES(?,?,?,?)", (column1, column2))
db.commit()

Python. DB-API(PyMySQL, PostgreSQL, ...). Cursors(cursor = connect.cursor()). One cursor on all queries, or one cursor per query?

For example PyMySQL. How will cursors be used more correctly?
Option 1:
connect = pymysql.connect()
cursor = connect.cursor()
cursor.execute('INSERT INTO user(name) VALUE('%s')', ('John',))
last_id = cursor.lastrowid
cursor.execute('SELECT name FROM user')
result = cursor.fetchall()
cursor.close()
Option 2:
connect = pymysql.connect()
cursor = connect.cursor()
cursor.execute('INSERT INTO user(name) VALUE('%s')', ('John',))
last_id = cursor.lastrowid
cursor.close()
cursor = connect.cursor()
cursor.execute('SELECT name FROM user')
result = cursor.fetchall()
cursor.close()
Those. Can I use a single cursor for all queries, or create a new cursor each time for a new query?
And, if you use one cursor for one type of query with different data? For example, option 3:
connect = pymysql.connect()
cursor = connect.cursor()
cursor.execute('INSERT INTO user(name) VALUE('%s')', ('John',))
last_id_1 = cursor.lastrowid
cursor.execute('INSERT INTO city(name) VALUE('%s')', ('Moskow',))
last_id_2 = cursor.lastrowid
cursor.close()
cursor = connect.cursor()
cursor.execute('SELECT name FROM user')
result_1 = cursor.fetchall()
cursor.execute('SELECT name FROM city')
result_2 = cursor.fetchall()
cursor.close()
Which option is better/more correct to use (and in terms of performance too)?
You don't need to Repeat it for Each Time. You Only need it one time..
// Creating the Connection
import pymysql.cursors
connection = pymysql.connect(host='localhost',
user='root',
password='pwd',
db='db',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
cursor = connection.cursor()
cursor.execute('INSERT INTO user(name) VALUE('%s')', ('John',))
last_id_1 = cursor.lastrowid
cursor.execute('INSERT INTO city(name) VALUE('%s')', ('Moskow',))
last_id_2 = cursor.lastrowid
cursor.execute('SELECT name FROM user')
result_1 = cursor.fetchall()
cursor.execute('SELECT name FROM city')
result_2 = cursor.fetchall()
cursor.close()
To apply the changes to DB for Insert or Update Query you should add the below code snippet also.
cursor.commit()

Categories