I am trying to insert a row into my postgresql database with a table created from
CREATE TABLE public.coinbase_btc_usd
(
id bigserial primary key,
price integer NOT NULL,
buy integer NOT NULL,
sell integer NOT NULL,
"timestamp" timestamp with time zone
)
However when my python 3.6 script runs and tries to add a row using psycopg2 like this it returns an error saying "no results to fetch" and nothing is added to my db.
sql_query = "INSERT INTO coinbase_btc_usd(price, buy, sell, timestamp)" \
" VALUES (" + exchange_rate + ', ' + buy_rate + ', ' + sell_rate + ", \'2015-10-10 06:44:33.8672177\')"
print(sql_query)
cur.execute(sql_query)
I also printed the sql_query variable to see exactly what was getting attempted to execute and this was printed to the output
INSERT INTO coinbase_btc_usd(price, buy, sell, timestamp) VALUES (16392.10, 16563.40, 16235.42, '2015-10-10 06:44:33.8672177')
Make sure that you are committing the transaction:
cur.execute(sql_query)
conn.commit()
Or you can enable auto commit to commit each query immediately after execution:
conn.autocommit = True
Furthermore, it costs nothing to prevent SQL injection attack - just use parametersied queries. In fact your code will actually be cleaner as well as safer:
sql_query = "INSERT INTO coinbase_btc_usd(price, buy, sell, timestamp) VALUES (%s, %s, %s, %s)"
cur.execute(sql_query, (exchange_rate, buy_rate, sell_rate, timestamp))
conn.commit()
change the
sql_query = "INSERT INTO coinbase_btc_usd(price, buy, sell, timestamp)" \
" VALUES (" + exchange_rate + ', ' + buy_rate + ', ' + sell_rate + ", \'2015-10-10 06:44:33.8672177\')"
to:
sql_query = "INSERT INTO coinbase_btc_usd(price, buy, sell, timestamp)" \
" VALUES (" + exchange_rate + ', ' + buy_rate + ', ' + sell_rate + ", \'2015-10-10 06:44:33.8672177\') returning *"
this should fix no results to fetch in my assumption.
If you see no row added, you most probably begin transaction and never commit it.
Related
conn = sqlite3.connect('business_database.db')
c = conn.cursor()
c.execute("INSERT INTO business VALUES(self.nob_text_input.text, self.post_text_input.text, self.descrip_text_input.text )")
conn.commit()
conn.close()
I want to add records into my database using the TextInput in kivy hence the 'self.post_text_input.text' etc, but I get this error:
OperationalError: no such column: self.nob_text_input.text
I tried putting the columns next to table name in the query:
c.execute("INSERT INTO business(column1, column2,column3) VALUES(self.nob_text_input.text....)
But I still get the same error.
Turning my comment into a more detailed answer.
If you're trying to use the values of the variables (self.nob_text_input.text and friends) in the string, you need to embed those values in the string.
One way is to use a format string:
"INSERT INTO business VALUES(%s, %s, %s)" % (self.nob_text_input.text, self.post_text_input.text, self.descrip_text_input.text)
And another is to just concatenate the strings:
"INSERT INTO business VALUES(" + self.nob_text_input.text + ", " + self.post_text_input.text + ", " + self.descrip_text_input.text + ")"
I am using pymyql/mysql-connector to write the messages to mysql database. The messages are processed on callback (paho.mqtt callback) from mqtt broker.I have 4 different tables and based on the message type, I am inserting messages into database. I have written the insert queries as below. this way of writing leads to sql injections it seems.Any suggestions how can I improve the insert query statements?
# callback attached to paho.mqtt.client
def on_message(self, client, userdata, msg):
if msg.topic.startswith("topic1/"):
self.bulkpayload += "(" + msg.payload.decode("utf-8") + "," + datetime + "),"
elif msg.topic.startswith("topic2/"):
self.insertStatement += "INSERT INTO mydatabase.table1 VALUES (" + msg.payload.decode("utf-8") + "," + datetime + ");"
elif msg.topic.startswith("topic3/")
self.insertStatement += "INSERT INTO mydatabase.table2 VALUES (" +msg.payload.decode("utf-8") + "," + datetime + ");"
elif msg.topic.startswith("messages"):
self.insertStatement += "INSERT INTO mydatabase.table3 VALUES ('" + msg.topic + "'," + msg.payload.decode("utf-8") + "," + datetime + ");"
else:
return # do not store in DB
cursor.execute(self.insertStatement)
cursor.commit()
Make your query use parameters. Much less chance of injection:
cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))
credit (and more info) here: How to use variables in SQL statement in Python?
Also, Dan Bracuk is correct - make sure you validate your params before executing the SQL if you aren't already
I have bottom MySql query (sql1).
sq1 = 'select course_id, creator_id, max(course_num) + 1, recordid
' from Courses where recordid in' \
' (' + ','.join(map(str, RecordMatch1)) + ') group by recordid'
cursor.execute(sql1)
BTW, RecordMatch1 is an object that has matching data from other previous queries.
I am trying to see if this is possible; (select * from sql1) portion.
sql2 = ' insert into Courses (course_id, creator_id, course_num, record_id) '\
' Values ( select * from sql1)'
cursor.execute(sql2)
Or do I have to express everything rather than using (Select * )?
What is best practice?
You can do this, but you should specify columns in case of schema changes.
Just need to confirm you are trying to run a select query and insert its output to a insert query. If that is the case this appears to be good.
yes, you can but you should do something like
sql = "SELECT course_id, creator_id, course_num, record_id FROM Courses"
all = cursor.fetchall()
for i in range(len(all))
sql1 = "INSERT INTO Courses (course_id, creator_id, course_num, record_id) VALUES (%s, %s, %s, %s)"
cursor.execute(sql1, (all[i]['Key'], all[i]['Key2'], all[i]['Key3'], all[i]['Key3']))
you can change the select like you want, remember that return a dictionary so take care about the keys, add print(all) to see what happen with the select and see the keys of each column
Information: inserting a statistic, that is a temperature value. The info should be "temp" so that I know that the log is about the temperature
I'm trying to execute next query from a python script
info = "temp"
sql = 'insert into stat_bus (addr, grp, info, status)
VALUES (' + address + ', ' + group + ', ' + info + ', ' + status + ')'
I get following error: Unknown column temp in field list
The address, group and status don't give erros.
I have tried other possibilities for the string parsing (I guess that's the error?) but can't get it working. Thanks in advance
The problem is that with your query, SQL isn't interpreting temp as a the string "temp", but as a variable named temp.
If you print sql, you will get the following query:
insert into stat_bus (addr, grp, info, status) VALUES (something, something, temp, something)
Whereas you would want this query:
insert into stat_bus (addr, grp, info, status) VALUES ("something", "something", "temp", "something")
(Note the quotes around temp)
Just change your Python code by adding the quotes in the right places:
info = "temp"
sql = 'insert into stat_bus (addr, grp, info, status)
VALUES ("' + address + '", "' + group + '", "' + info + '", "' + status + '")'
I have written a small script to create a MySQL database, create a table (previously erase it if already exists), and insert many entries. When I execute my script, it works creating the database and table, but does not write any entry to the table:
from warnings import filterwarnings
import MySQLdb as db
filterwarnings('ignore', category = db.Warning)
try:
db_name = 'chom'
con = db.connect(user='user', passwd='pass')
cur = con.cursor()
# Create new database
cur.execute('CREATE DATABASE IF NOT EXISTS ' + db_name + ';')
# Create PARAMETERS table
cur.execute('DROP TABLE IF EXISTS ' + db_name + '.PARAMETERS;')
query = ('CREATE TABLE ' + db_name + '.PARAMETERS ('
'idPARAMETERS INT(10) NOT NULL AUTO_INCREMENT, '
'Param_name VARCHAR(30) NULL DEFAULT NULL, '
'Param_value VARCHAR(255) NULL DEFAULT NULL, '
'Timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP '
'ON UPDATE CURRENT_TIMESTAMP, '
'User_id VARCHAR(20) NULL DEFAULT NULL, '
'PRIMARY KEY (idPARAMETERS) );'
)
cur.execute(query)
# Insert entries
parameters = ['param1', 'param2', 'param3',
'param4']
for i, param_name in enumerate(parameters, start=1):
cur.execute('INSERT INTO ' + db_name + '.PARAMETERS '
'(idPARAMETERS, Param_name, Param_value, User_id) '
'VALUES (' + str(i) + ', %s, %s, %s);',
(param_name, '', 'user2#localhost'))
cur.close()
con.commit()
except Exception, e:
print 'Error. Last query: ' + str(cur._last_executed)
print e
print 'DB installation script finished'
I can't see where the problem is. Any idea?
The code worked correctly, it was mysql-workbench fault, which was not showing the correct database content (while mysql console client did).