SQLite: INSERT or REPLACE w/ null PRIMARY KEY - python

I am trying to INSERT or REPLACE INTO t1 if the name is already there. I understand if the id is set then replace will work, but I need it to react to name.
import sqlite3
def insert(name):
cur.execute('INSERT OR REPLACE INTO t1(name) VALUES(?)', [name])
def select():
return cur.execute('SELECT * FROM t1').fetchall()
conn = sqlite3.connect('test')
cur = conn.cursor()
cur.execute('DROP TABLE IF EXISTS t1')
cur.execute('''CREATE TABLE IF NOT EXISTS t1(
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
)''')
insert('jack')
insert('jack')
insert('jack')
print select()
output
[(1, u'jack'), (2, u'jack'), (3, u'jack')]

INSERT or REPLACE ... will do replace only if there are collisions. And as your name column isnt collidable, this event cannot accur (at least not on name). You need to make name collidable:
CREATE UNIQUE INDEX IF NOT EXISTS iname ON t1 (name)
Also note that you dont need to have id column, because sqlite3 has ROWID on every table.

Related

Auto Incrementing Primary Key Using Entry Widgets into Table

I'm using entries to insert data points into a table where the 'ID' is auto-incrementing. I'm encountering an issue I had when I was working on importing a table with the id being based on auto incrementing, but the solutions I got for that haven't worked with this so far.
import tkinter as tk
import sqlite3
c.execute("""CREATE TABLE IF NOT EXISTS tbl (
id INTEGER PRIMARY KEY NOT NULL,
data text
)""")
def add_equipment():
conn = sqlite3.connect('database.db')
c = conn.cursor()
c.execute("INSERT INTO tbl VALUES(:ID + null, :data)
{"data":data_ent.get()
})
conn.commit()
conn.close()
Doing this gives me an error of did not supply value for binding parameter id, removing the ':id + null' gives me an error of 1 column doens't have a supplied value. I used a for loop on the import version of this, but when I tried to do a loop as:
for row in c.fetchall():
c.execute('variable for the insert command & data', row)
it gives me no error, but doesn't insert the data into the table. I assume the for loop is wrong, but I'm not sure what it should be since this is meant to insert a single record at a time.
def add_equipment():
conn = sqlite3.connect('database.db')
c = conn.cursor()
c.execute("INSERT INTO tbl VALUES(:ID + null, :data)
{"id":'NULL',
"data":data_ent.get()
})
conn.commit()
conn.close()
This gives id a binding parameter and allows the null to auto increment as supposed to.

"Delete from" deletes everything

I have a python function that deletes a row in mysql table using name attribute as a condition:
def delete(table: str, name: str):
cursor.execute(f"DELETE FROM {table} WHERE name = {name}")
conn.commit()
I have one row with a name attribute equal to "Name". When I use this function with "Name" it deletes every single row in a table.
I'm guessing that it has to do with passed string being same as attribute. But what would be the solution to that problem except renaming attributes?
So for one, I think you are missing quotes around name, as well as a semicolon.
For further reading you should also take a look at Python parameterized query and Prepared Statement
I do agree with the comments, that table should not be an injected argument for security reasons!
def delete(table: str, name: str):
query = f"DELETE FROM {table} WHERE name = ?"
print(query)
cursor.execute(query, (name,))
conn.commit()`
EDIT FULL WORKING EXAMPLE:
import sqlite3
conn = sqlite3.connect("test")
query_create = '''CREATE TABLE IF NOT EXISTS projects (
id integer PRIMARY KEY,
name text NOT NULL,
begin_date text,
end_date text
);'''
conn.execute(query_create)
query_insert = '''insert into projects (id, name, begin_date, end_date) values (1,"name","date","date")'''
conn.execute(query_insert)
query_select = '''select * from projects'''
cur = conn.execute(query_select)
print(cur.fetchall())
def delete(table: str, name: str):
query = f"DELETE FROM {table} WHERE name = ?"
print(query)
conn.execute(query, (name,))
delete('projects', 'name')
cur = conn.execute(query_select)
print(cur.fetchall())
Gives Output:
[(1, 'name', 'date', 'date')]
DELETE FROM projects WHERE name = ?
[]

Python sqlite how to alter table add columb if not exists

I want: if column not exists, add column
def tablo_olustur():
cursor.execute("CREATE TABLE IF NOT EXISTS "+asin+"(Tarih TEXT)")
con.commit()
tablo_olustur()
def veri_ekle(Satıcı_ismi,Stok_Miktarı):
cursor.execute("INSERT INTO "+asin+' (Tarih, "{}") values (?,?)'.format(Satıcı_ismi),(currentDT,Stok_Miktarı))
con.commit()
#def ver_ekle2(Stok_Miktarı):
# cursor.execute("INSERT INTO "+asin+" (Satıcı_ismi, '{}') values (?,?)".format(currentDT),(Satıcı_ismi,Stok_Miktarı))
# con.commit()
def sutun_ekle(sutun):
cursor.execute("ALTER TABLE "+asin+' ADD COLUMN "{}" '.format(sutun))
con.commit()
I get sqlite3.OperationalError: duplicate column name: xxxx error from python
You can try this, if column exists it will add if not you can check if any column of same name already exists in the table
def sutun_ekle(sutun):
try:
cursor.execute("ALTER TABLE "+asin+' ADD COLUMN "{}" '.format(sutun))
con.commit()
except:
cursor.execute("PRAGMA table_info(asin)")
print cursor.fetchall() #prints the list of existing column header
You need to inspect your table to see whether the column exists:
# replace your_table with your table you want to inspect
existing_cols = [row.column_name for row in cursor.columns(table='your_table')
# check if the column you want to add is in the list
if col_add in existing_cols:
pass # do nothing
else:
# alter table
# replace your_table with the table you want to alter
# replace varchar(32) with the data type for the column
cursor.execute("ALTER TABLE your_table ADD COLUMN {} varchar(32)".format(col_add)
con.commit()

Creating database in Python using sqlite3

I got stuck when I was trying to create database in Python using sqlite3. The below is what I did. When I tried to run, it kept telling me the tables already exist. I couldn't figure out why. Thanks!
import sqlite3
variables = (data)
functions = (data)
var_func = (data)
conn = sqlite3.connect('python_database')
c = conn.cursor()
#create table
c.execute(''' CREATE table variable_table (
id integer,
name text,
module text,
type text,
desc text) ''')
c.execute(''' CREATE table function_table (
id integer,
name text) ''')
c.execute(''' CREATE table var_func_table (
variable_id integer,
function_id integer,
type text) ''')
#fill tables with data
for row in variables:
c.execute ('insert into variable_table values (?,?,?,?,?)', row )
for row in functions:
c.execute ('insert into function_table values (?,?)', row)
for row in var_func:
c.execute ('insert into var_func_table values (?,?,?)', row)
# Save (commit) the change
conn.commit
conn.close

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