How do could I insert a certain value into a specific column - python

import sqlite3 as db
def criar_grupos():
global cursor3,nome_grupo
nome_grupo = raw_input('name of group')
nome_criador = raw_input('new user')
conn3 = db.connect("tabela_grupos.db")
cursor3 = conn3.cursor()
cursor3.execute('CREATE TABLE IF NOT EXISTS groups (name string NOT NULL
UNIQUE)')
conn3.commit()
cursor3.execute("alter table grupos add column '%s' 'string'" %
nome_grupo)
cursor3.execute('UPDATE grupos SET ("nome"=?) WHERE name=?',
(nome_grupo, nome_criador))
criar_grupos()
I'm having a bad time trying to execute this function.
I keep getting the error message:
sqlite3.OperationalError: near "(": syntax error
What could I be doing wrong.?

INSERT INTO <table> (col1, col2, col5) VALUES ('val1','val2','val5');

Change this:
cursor3.execute('UPDATE grupos SET ("nome"=?) WHERE name=?', (nome_grupo, nome_criador))
To this:
cursor3.execute('INSERT INTO grupos (?) VALUES (?);', (nome_grupo, nome_criador))

Related

Cannot INSERT strings with Set Clause with mariadb connector (python)

I want to insert a new row in my table by using the python-mariadb connector. For that I prefer to use the SET clause.
For some reason it does work if I only want to save ints (i.e y=2), but when I use a string, the following error occurs
Unknown column 'myString' in 'field list'
It seems it thinks the content of the string is a column name? Any idea how to fix that (I can do it with INSERT INTO ... VALUES ..., but I want to use the SET clause here). From my understanding, it should save both an int and a str without throwing an error
Thank you.
See the code example below
def myfunction():
x = 1
y ='myString'
db = connect_db()
cur = db.cursor()
sql = "INSERT INTO Table SET col1={}, col2={}"
cur.execute(sql.format(x, y))
db.commit()
db.close()
return
Here the MariaDB Connector, but this should be fine as it works for other db functions.
import mariadb
def connect_db():
db = mariadb.connect(
user="user",
password="123",
host="localhost",
port=3306,
database="DB"
)
db.autocommit = False
return db
you are not using right syntax for insert
sql = "INSERT INTO Table (col1,col2) values({}, {})"
but if you want to update an existing row:
sql = "UPDATE Table SET col1={}, col2={} WHERE id = {}"
and probably you need a where clause
The code in question produces the SQL statement:
INSERT INTO Table SET col1=1, col2=myString;
This is incorrect syntax, and strings must be in single-quotes:
INSERT INTO Table (col1, col2) VALUES (1, 'myString');
def myfunction():
x = 1
y ='myString'
db = connect_db()
cur = db.cursor()
sql = "INSERT INTO Table (col1, COL2) VALUES ({}, '{}')"
cur.execute(sql.format(x, y))
db.commit()
db.close()
return
But the above is fragile. Don't use string building methods to create SQL statements, it is much better to use parameter binding.
def myfunction():
x = 1
y ='myString'
db = connect_db()
cur = db.cursor()
sql = "INSERT INTO Table (col1, col2) VALUES (?, ?)"
cur.execute(sql, (x, y))
db.commit()
db.close()
return
The MariaDB connector documentation explains these things.
Retrieving Data
Once you have the initial code in place you can start working with the data. The first thing you should do is try to
retrieve information from the database. Here is code for a query
against the employees database:
cur.execute(
"SELECT first_name,last_name FROM employees WHERE first_name=?",
(some_name,))
MariaDB Connector/Python uses prepared statements, sanitizing and inserting the values from the tuple into the position
of the question marks (?). This is safer than inserting through
f-strings or format specifiers when working with user provided
information.
The query results are stored in a list in the cursor object. To view
the results, you can loop over the cursor.
Adding Data
Using the same execute() method with an INSERT statement, you can add rows to the table.
cursor.execute(
"INSERT INTO employees (first_name,last_name) VALUES (?, ?)",
(first_name, last_name))

Is there a way using SQLite and Python to write an insert statement with the columns as parameters?

I am trying to clean raw json data by parsing and inserting it into a table of an sqlite db.
I have 22 columns in my table and want to find a way of looping through them so I don't need to write 22 loops which insert the data or a single column.
I have simplified the approach I am trying with the following:
import sqlite3
conn = sqlite3.connect('cdata.sqlite')
cur = conn.cursor()
column = 'name'
value = 'test'
cur.execute('''INSERT INTO COMPANY (?)
VALUES (?)''',(column,),(value,))
conn.commit()
conn.close()
This doesn't work at the moment and return the error TypeError: function takes at most 2 arguments (3 given).
Does anyone know if it is possible to write an SQLite insert statement using 2 parameters like this or another way I might be able to iterate through the columns?
Sample as below:
import sqlite3
conn = sqlite3.connect("cdata.sqlite")
cur = conn.cursor()
column = ("name", "age")
table = f"CREATE TABLE IF NOT EXISTS COMPANY ({column[0]} text, {column[1]} text);"
cur.execute(table)
name = "hello"
age = "1"
sql_stmt = f"INSERT INTO COMPANY({column[0]},{column[1]}) VALUES ('{name}', '{age}')"
cur.execute(sql_stmt)
with conn:
cur.execute("SELECT * FROM COMPANY")
print(cur.fetchall())
conn.commit()
conn.close()

sqlite3.OperationalError: near "CASE": syntax error

I'm trying to insert data into sql table like this
conn = sqlite3.connect('Tags.db')
cur = conn.cursor()
input = open('word_freq_list.txt', 'r', encoding = 'UTF-8')
for word in input.read().split():
p = morph.parse(word)[0]
pos = p.tag.POS
case = p.tag.case
num = p.tag.number
gender = p.tag.gender
cur.execute(''' INSERT INTO Words_with_tags (POS, CASE, NUM, GENDER)
VALUES (?, ?, ?, ?)''', (pos, case, num, gender))
conn.commit()
But every I'm getting an error message:
sqlite3.OperationalError: near "CASE": syntax error
I can't understand why: column names are placed in the right order, the names are right too.
CASE is a Reserved Word, you can't use it as a column or variable name in your SQL query. Try using another column name instead of CASE.

insert into mysql database with pymysql failing to insert

I'm trying to insert dummy data into a mysql database.
The database structure looks like:
database name: messaround
database table name: test
table structure:
id (Primary key, auto increment)
path (varchar(254))
UPDATED 2 method below, and error.
I have a method to try to insert via:
def insert_into_db(dbcursor, table, *cols, **vals):
try:
query = "INSERT INTO {} ({}) VALUES ('{}')".format(table, ",".join(cols), "'),('".join(vals))
print(query)
dbcursor.execute(query)
dbcursor.commit()
print("inserted!")
except pymysql.Error as exc:
print("error inserting...\n {}".format(exc))
connection=conn_db()
insertstmt=insert_into_db(connection, table='test', cols=['path'], vals=['test.com/test2'])
However, this is failing saying:
INSERT INTO test () VALUES ('vals'),('cols')
error inserting...
(1136, "Column count doesn't match value count at row 1")
Can you please assist?
Thank you.
If you use your code:
def insert_into_db(dbcursor, table, *cols, **vals):
query = "INSERT INTO {} ({}) VALUES ({})".format(table,",".join(cols), ",".join(vals))
print(query)
insert_into_db('cursor_here', 'table_here', 'name', 'city', name_person='diego', city_person='Sao Paulo')
Python returns:
INSERT INTO table_here (name,city) VALUES (name_person,city_person)
Now with this other:
def new_insert_into_db(dbcursor, table, *cols, **vals):
vals2 = ''
for first_part, second_part in vals.items():
vals2 += '\'' + second_part + '\','
vals2 = vals2[:-1]
query = "INSERT INTO {} ({}) VALUES ({})".format(table,",".join(cols), vals2)
print(query)
new_insert_into_db('cursor_here', 'table_here', 'name', 'city', name_person='diego', city_person='Sao Paulo')
Python will return the correct SQL:
INSERT INTO table_here (name,city) VALUES ('diego','Sao Paulo')
Generally in Python you pass a parameterized query to the DB driver. See this example in PyMySQL's documentation; it constructs the INSERT query with placeholder characters, then calls cursor.execute() passing the query, and a tuple of the actual values.
Using parameterized queries is also recommended for security purposes, as it defeats many common SQL injection attacks.
you should print the sql statement which you've generated, that makes it a lot easier to see what's wrong.
But I guess you need quotes ' around string values for your ",".join(vals) (in case there are string values.
So your code is producing
insert into test (path,) values (test.com/test2,);
but it should produce
insert into test (`path`) values ('test.com/test2');
Otherwise try https://github.com/markuman/MariaSQL/ which makes it super easy to insert data to MariaDB/MySQL using pymysql.
Change your query as below
query = "INSERT INTO {} ({}) VALUES ('{}')".format(table, ",".join(cols), "'),('".join(vals))
As you are using join, the variable is expected to be a list but not a string
table = 'test'
cols = ['path']
vals = ['test.com/test2', 'another.com/anothertest']
print(query)
"INSERT INTO test (path) VALUES ('test.com/test2'),('another.com/anothertest')"
Update:
def insert_into_db(dbconnection=None, table='', cols=None, vals=None):
mycursor = dbconnection.cursor()
if not (dbconnection and table and cols and vals):
print('Must need all values')
quit()
try:
query = "INSERT INTO {} ({}) VALUES ('{}')".format(table, ",".join(cols), "'),('".join(vals))
mycursor.execute(query)
dbconnection.commit()
print("inserted!")
except pymysql.Error as exc:
print("error inserting...\n {}".format(exc))
connection=conn_db()
insertstmt=insert_into_db(dbconnection=connection, table='test', cols=['path'], vals=['test.com/test2'])

PyQt ComboBox results not working in MySQL

I am writing a program in which two variables are selected from QCombobBoxes which are populated with results from a MySQL query. I then take these variable and insert them into a MySQLdb statement that inserts the variables into a different MySQL table. The first variable works fine, however on the second I get this error,
TypeError: 'NoneType' object has no attribute '__getitem__'
The code is identical for both variables, with the exception of different names
name = str(self.item_name.currentText())
cur.execute("SELECT item_id FROM Items WHERE name = '%s';"), name
db.commit()
results = cur.fetchone()
item_name = results[0]
personnel_name = str(self.purchaser_name.currentText())
cur.execute("SELECT personnel_id FROM Personnel WHERE name = '%s';"), personnel_name
db.commit()
results = cur.fetchone()
purchaser_id = results[0]
After playing with it, it looks like cur.execute("SELECT item_id FROM Items WHERE name = '%s';"), name is inserting an extra pair of quotation marks around the value that replaces %s Does anyone know why it's doing this and how to stop it? I coded both variables exactly the same, and it seems that name is getting an extra pair of quotes from MySQL
This is code that populates QComboBox:
#Get list of items currently in the database
cur = db.cursor()
cur.execute("SELECT name FROM Items")
db.commit()
results = cur.fetchall()
for name in results:
self.item_name.addItem(name[0])
#Get list of purchaser names
cur.execute("SELECT name FROM Personnel")
db.commit()
results = cur.fetchall()
for name in results:
self.purchaser_name.addItem(name[0])
If I manually insert a variable, it works fine. ex: cur.execute("SELECT item_id FROM Items WHERE name = 'Wire';") Only when I use string formatting with %s does the error occurr.
c.execute("SELECT * FROM sometable WHERE some_condition=?","My Condition")
you should always use the ? placeholders for this kind of thing
[edit]
try 1. cur.execute("SELECT item_id FROM Items WHERE name = '%s';"%(name,))
or 2. cur.execute("SELECT item_id FROM Items WHERE name = %s;", (name,))
from my brief reading, I think that mysql driver will automatically quote %s arguments
my conclusion is that cur.execute("SELECT item_id FROM Items WHERE name = %s;", (name,)) is the most correct way to do this(to avoid injection etc).

Categories