sqlite transaction doesn't commit - python

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()

Related

make temporary database with sqlite

I wanna make a temporary database but I don't know I going in the right way or not
I get the error no such table: list but I don't know why python raise that error
this is my code:
def connect():
conn = sqlite3.connect(":memory:")
cur = conn.cursor()
cur.execute(
"CREATE TABLE IF NOT EXISTS list (id INTEGER PRIMARY KEY , namee VARCHAR , number INTEGER ,"
" price INTEGER )"
)
conn.commit()
conn.close()
def insert(name, number, price):
conn = sqlite3.connect(":memory:")
cur = conn.cursor()
cur.execute(
"INSERT INTO list VALUES (NULL ,?,?,?,?,?)", (name, number, price)
)
conn.commit()
conn.close()
def view():
conn = sqlite3.connect(":memory:")
cur = conn.cursor()
cur.execute(
"SELECT * FROM list"
)
rows = cur.fetchall()
conn.close()
return rows
def delete(id):
conn = sqlite3.connect(":memory:")
cur = conn.cursor()
cur.execute("DELETE FROM list WHERE id=?", (id,))
conn.commit()
conn.close()
connect()
and this is my error:
Traceback (most recent call last):
File "D:\python\WindowsProject\app\user\memory.py", line 42, in <module>
print(insert('pizza',2,6))
File "D:\python\WindowsProject\app\user\memory.py", line 17, in insert
cur.execute(
sqlite3.OperationalError: no such table: list
sqlite3.connect(":memory:") creates an in-memory database that only exists as long as the connection is in use.
The problem is that you're closing the database connection in each function. As soon as you close it, the in-memory database vanishes. INSERT fails because the table no longer exists.
You'll need to preserve (or pass) the conn and cur objects so that you can use them between functions.

how to use one database in several python file

I working on a project and I want to use one database in two python file
but, when I run every project they created database for self
if you know please tell me how I can use that
import sqlite3
def connect():
conn = sqlite3.connect("waiters.db")
cur = conn.cursor()
cur.execute(
"CREATE TABLE IF NOT EXISTS salary (id INTEGER PRIMARY KEY , name text, age INTEGER , price INTEGER )"
)
conn.commit()
conn.close()
def insert(name, age, price):
conn = sqlite3.connect("waiters.db")
cur = conn.cursor()
cur.execute(
"INSERT INTO salary VALUES (NULL ,?,?,?)", (name ,age ,price)
)
conn.commit()
conn.close()
def view():
conn = sqlite3.connect("waiters.db")
cur = conn.cursor()
cur.execute(
"SELECT * FROM salary"
)
rows = cur.fetchall()
conn.close()
return rows
def search(name="", age="", price=""):
conn = sqlite3.connect("waiters.db")
cur = conn.cursor()
cur.execute(
"SELECT * FROM salary WHERE name = ? OR age = ? OR price = ?", (name, age, price)
)
rows = cur.fetchall()
conn.close()
return rows
def delete(id):
conn = sqlite3.connect("waiters.db")
cur = conn.cursor()
cur.execute("DELETE FROM salary WHERE id=?", (id,))
conn.commit()
conn.close()
def update(id, name, age, price):
conn = sqlite3.connect("waiters.db")
cur = conn.cursor()
cur.execute(
"UPDATE salary SET name = ?, age = ?, price = ? WHERE id = ?", (name, age, price, id)
)
conn.commit()
conn.close()
def update_pay_money(name, price):
conn = sqlite3.connect("waiters.db")
cur = conn.cursor()
cur.execute(
"UPDATE salary SET price = ? WHERE name = ?", (price, name)
)
conn.commit()
conn.close()
connect()
enter image description here
Giving exact path like /path/to/waiters.db while connecting to your database should solve your problem?
This line should be changed while connecting to database.
conn = sqlite3.connect("/path/to/waiters.db")
as Other mentioned for using a sqllite3 db in multiple files you can use their absolute or relative path, for example if you have 'DBs' & 'section-1' & 'section-2' directories and your python file are in section directories you can access the database file in each section by using somthing like this '"../DBs/waiters.db"' and so on for others... but whatf of you try make multiple tables in a database file in tgat way you don need to have multiple databases and its the standard way,
hope it's help

psycopg2: update multiple rows with one query

I tried to update multiple rows (approx. 350000) with a single query by implementing the following function:
def update_items(rows_to_update):
sql_query = """UPDATE contact as t SET
name = e.name
FROM (VALUES %s) AS e(id, name)
WHERE e.id = t.id;"""
conn = get_db_connection()
cur = conn.cursor()
psycopg2.extras.execute_values (
cur, sql_query, rows_to_update, template=None, page_size=100
)
While trying to run the function above, only 31 records were updated. Then, I tried to update row by row with the following function:
def update_items_row_by_row(rows_to_update):
sql_query = """UPDATE contact SET name = %s WHERE id = %s"""
conn = get_db_connection()
with tqdm(total=len(rows_to_update)) as pbar:
for id, name in rows_to_update:
cur = conn.cursor()
# execute the UPDATE statement
cur.execute(sql_query, (name, id))
# get the number of updated rows
# Commit the changes to the database
conn.commit()
cur.close()
pbar.update(1)
The latter has updated all the records so far but is very slow (estimated to end in 9 hours).
Does anyone know what is the efficient way to update multiple records?
By splitting the list into chunks of size equal to page_size, it worked well:
def update_items(rows_to_update):
sql_query = """UPDATE contact as t SET
name = data.name
FROM (VALUES %s) AS data (id, name)
WHERE t.id = data.id"""
conn = get_db_connection()
cur = conn.cursor()
n = 100
with tqdm(total=len(rows_to_update)) as pbar:
for i in range(0, len(rows_to_update), n):
psycopg2.extras.execute_values (
cur, sql_query, rows_to_update[i:i + n], template=None, page_size=n
)
conn.commit()
pbar.update(cur.rowcount)
cur.close()
conn.close()
The problem with your original function appears to be that you forgot to apply commit. When you execute an insert/update query with psycopg2 a transaction is opened but not finalized until commit is called. See my edits in your function (towards the bottom).
def update_items(rows_to_update):
sql_query = """UPDATE contact as t SET
name = e.name
FROM (VALUES %s) AS e(id, name)
WHERE e.id = t.id;"""
conn = get_db_connection()
cur = conn.cursor()
psycopg2.extras.execute_values(cur, sql_query, rows_to_update)
## solution below ##
conn.commit() # <- We MUST commit to reflect the inserted data
cur.close()
conn.close()
return "success :)"
If you don't want to call conn.commit() each time you create a new cursor, you can use autocommit such as
conn = get_db_connection()
conn.set_session(autocommit=True)

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.

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