value is being read in as column title in mysql query - python

I am trying to add data to a mysql database. Can someone explain why the query seems to be treating temp as a column instead of the string value it is supposed to be?
pi#raspberrypi ~/Desktop/PiControl $ python writedb.py
rollback: (1054, "Unknown column 'temp' in 'field list'")
done
my table
mysql> select * from logs;
+----+--------+---------+------+
| id | sensor | reading | time |
+----+--------+---------+------+
| 1 | temp | NULL | NULL |
| 2 | NULL | 69.69 | NULL |
| 3 | NULL | 69.69 | NULL |
| 4 | NULL | 1234.56 | NULL |
| 5 | NULL | 1234.56 | NULL |
| 6 | NULL | 1234.56 | NULL |
| 7 | temp | 123 | NULL |
| 8 | temp | 20 | NULL |
+----+--------+---------+------+
8 rows in set (0.00 sec)
The script:
import MySQLdb
conn = MySQLdb.connect(host= "localhost",user="xx",passwd="yy",db="homelog")
x = conn.cursor()
try:
x.execute("INSERT INTO `logs` (`sensor`,`reading`) VALUES (`temp`,`4242`)")
#print x.execute("SELECT * FROM logs") #returns number of rows in table for some reason
conn.commit()
except Exception, e:
print 'rollback: ',e
conn.rollback()
conn.close()
print "done"

Try parameterizing your query avoiding using backticks for column values:
sensor = "temp"
reading = 4242
x.execute("INSERT INTO `logs` (`sensor`,`reading`) VALUES (%s, %s)", (sensor, reading))
print x.execute("SELECT * FROM logs") #returns number of rows in table for some reason
You need to fetch all the matching records from the cursor after executing:
sensor = "temp"
reading = 4242
x.execute("INSERT INTO `logs` (`sensor`,`reading`) VALUES (%s, %s)", (sensor, reading))
conn.commit()
x.execute("SELECT * FROM logs")
print(x.fetchall())

Related

MySQL's type isn't wrong,but MySQL tell the wrong 1064

thank you very much! I use 'renew' to replace 'update'. and it success! #MrTux
Thank you for help me.
mysql error:1064,but my type isn't wrong
python3+mysql+pymysql
mysql table:(you just need to see the 'update')
(if I insert into not include update , it will success.)
mysql> desc House;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| ID | int(11) | NO | PRI | NULL | auto_increment |
| num | varchar(30) | NO | UNI | NULL | |
| url | varchar(150) | YES | | NULL | |
| name | varchar(50) | YES | | NULL | |
| maintain | varchar(30) | YES | | NULL | |
| update | varchar(30) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
Code:
update = "a str"
sql2 = "INSERT INTO House (num,update) VALUES ('{0}' , '{1}' )".format(num,update)
print(sql2)
try:
cursor.execute(sql2)
print("sql2 success")
connect.rollback()
print("rollback success")
except Exception as e:
print("sql2 wrong:" + str(e))
Error:
INSERT INTO House (num,update) VALUES ('NJ2578781985216667648' , 'a str' )
sql2 wrong:(1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'update) VALUES ('NJ2578781985216667648' , 'a str' )' at line 1")
You get a syntax error because update is a keyword in MySQL. You need to use a different name or quote using backticks:
sql2 = "INSERT INTO House (num,`update`) VALUES ('{0}' , '{1}' )".format(num,update)
PS: please also be aware of possible SQL injections.

How can I prevent duplicate information from entering the mysql database?

In this program I created a database called mydata and I created a table called mining and I wanted to read my name and last name and age from a list in and if it was not in the database, save it in the database . But I got into trouble and my program gives an error.
In fact, in writing SQL syntax, it would store the data in the database if it did not exist. I have a problem
mycode:
import mysql.connector
cnx = mysql.connector.connect(
host='localhost',
user = 'root',
password = '',
database = 'mydata'
)
c = cnx.cursor()
list_number = ['mobin','ghanbari',15]
for i in list_number:
c.execute('INSERT INTO mining VALUES ("%s","%s","%s") WHERE NOT EXISTS (SELECT * FROM mining)'%(i,i,i))
Please help me solve this problem
You need to add unique index for the fields you do not want duplicate
Here an example with 3 fields . You can with multiple fields
mysql> ALTER TABLE mining ADD UNIQUE INDEX(your_field1, your_field2,your_field3);
And use INSERT IGNORE instead of INSERT . This prevent query to insert same data two or more times in the table
for i in list_number:
c.execute('INSERT IGNORE INTO mining VALUES ("%s","%s","%s") )
Or execute a query:
SELECT * FROM mining WHERE
your_field1 = 'mobin' AND
your_field2 = 'ghanbari' AND
your_field3 = 15;
Before the query INSERT .
if the SELECT query return something do not execute the INSERT query. Otherwise do the INSERT query.
You should make the columns you don't want duplicate information in unique. This way, when you try putting duplicate information in them, SQL will send a failure message to you in Python.
For example, take this table:
username (unique)
password
myusername
mypassword
When you try adding [newusername,newpassword], it won't give any error.
username (unique)
password
myusername
mypassword
newusername
newpassword
If we insert [anotherusername,mypassword], it won't give an error because password isn't unique
username (unique)
password
myusername
mypassword
newusername
newpassword
anotherusername
mypassword
But when we try inserting [myusername,anotherpassword], SQL will return an error to Python saying that since the username column is unique, it wasn't able to insert duplicate data (myusername is duplicate).
username (unique)
password
myusername
mypassword
newusername
newpassword
anotherusername
mypassword
See this tutorial to learn how to make a column unique.
Access to mysql
$ mysql -u root -p
Creating Database and table as example on mysql from command line.
mysql> CREATE DATABASE sof;
Query OK, 1 row affected (0.00 sec)
mysql> use sof;
Database changed
mysql> CREATE TABLE mining (
-> id int NOT NULL AUTO_INCREMENT,
-> lastname varchar(255) NOT NULL,
-> firstname varchar(255),
-> age int,
-> PRIMARY KEY (id)
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> show tables;
+---------------+
| Tables_in_sof |
+---------------+
| mining |
+---------------+
mysql> explain mining;
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| lastname | varchar(255) | NO | | NULL | |
| firstname | varchar(255) | YES | MUL | NULL | |
| age | int(11) | YES | | NULL | |
+-----------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> ALTER TABLE mining ADD UNIQUE INDEX(firstname, lastname, age);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW INDEXES FROM mining;
+--------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| mining | 0 | PRIMARY | 1 | id | A | 2 | NULL | NULL | | BTREE | | |
| mining | 0 | firstname | 1 | firstname | A | 2 | NULL | NULL | YES | BTREE | | |
| mining | 0 | firstname | 2 | lastname | A | 2 | NULL | NULL | | BTREE | | |
| mining | 0 | firstname | 3 | age | A | 3 | NULL | NULL | YES | BTREE | | |
+--------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
4 rows in set (0.00 sec)
Please note the field Non_unique
1 if the index can contain duplicates, 0 if it cannot.
Now the Python Script:
import mysql.connector
mydb = mysql.connector.connect(
host='localhost',
user = 'root',
password = '',
database = 'sof'
)
cursor = mydb.cursor()
listd =[
{'firstname':'mobin1','lastname':'ghanbari1','age':15},
{'firstname':'mobin2','lastname':'ghanbari2','age':16},
{'firstname':'mobin3','lastname':'ghanbari3','age':17},
{'firstname':'mobin4','lastname':'ghanbari4','age':18}
]
for row in listd:
sql = "INSERT INTO mining (firstname, lastname , age) VALUES (%s, %s, %s)"
val = (row['firstname'],row['lastname'], row['age'])
try:
cursor.execute(sql, val)
mydb.commit()
print(cursor.rowcount, "record inserted for "+row["firstname"])
except mysql.connector.Error as err:
print("mysql exception: {}".format(err))
print(cursor.rowcount, "record inserted for "+row["firstname"])
Output:
1 record inserted for mobin1
1 record inserted for mobin2
1 record inserted for mobin3
1 record inserted for mobin4
Checking on mysql if records was inserted
mysql> select * from mining;
+----+-----------+-----------+------+
| id | lastname | firstname | age |
+----+-----------+-----------+------+
| 1 | ghanbari1 | mobin1 | 15 |
| 2 | ghanbari2 | mobin2 | 16 |
| 3 | ghanbari3 | mobin3 | 17 |
| 4 | ghanbari4 | mobin4 | 18 |
+----+-----------+-----------+------+
4 rows in set (0.00 sec)
Adding some data in the list of Python script*
import mysql.connector
mydb = mysql.connector.connect(
host='localhost',
user = 'root',
password = '',
database = 'sof'
)
cursor = mydb.cursor()
listd =[
{'firstname':'mobin1','lastname':'ghanbari1','age':15},
{'firstname':'mobin2','lastname':'ghanbari2','age':16},
{'firstname':'mobin3','lastname':'ghanbari3','age':17},
{'firstname':'mobin4','lastname':'ghanbari4','age':18},
{'firstname':'mobin5','lastname':'ghanbari5','age':19},
{'firstname':'mobin6','lastname':'ghanbari6','age':20},
{'firstname':'mobin7','lastname':'ghanbari7','age':21}
]
for row in listd:
sql = "INSERT INTO mining (firstname, lastname , age) VALUES (%s, %s, %s)"
val = (row['firstname'],row['lastname'], row['age'])
try:
cursor.execute(sql, val)
mydb.commit()
print(cursor.rowcount, "record inserted for "+row["firstname"])
except mysql.connector.Error as err:
print("mysql exception: {}".format(err))
print(cursor.rowcount, "record inserted for "+row["firstname"])
Running the Python Script
Output:
mysql exception: 1062 (23000): Duplicate entry 'mobin1-ghanbari1-15' for key 'firstname'
-1 record inserted for mobin1
mysql exception: 1062 (23000): Duplicate entry 'mobin2-ghanbari2-16' for key 'firstname'
-1 record inserted for mobin2
mysql exception: 1062 (23000): Duplicate entry 'mobin3-ghanbari3-17' for key 'firstname'
-1 record inserted for mobin3
mysql exception: 1062 (23000): Duplicate entry 'mobin4-ghanbari4-18' for key 'firstname'
-1 record inserted for mobin4
1 record inserted for mobin5
1 record inserted for mobin6
1 record inserted for mobin7
Checking on mysql if we have duplicate entries
mysql> select * from mining;
+----+-----------+-----------+------+
| id | lastname | firstname | age |
+----+-----------+-----------+------+
| 1 | ghanbari1 | mobin1 | 15 |
| 2 | ghanbari2 | mobin2 | 16 |
| 3 | ghanbari3 | mobin3 | 17 |
| 4 | ghanbari4 | mobin4 | 18 |
| 13 | ghanbari5 | mobin5 | 19 |
| 14 | ghanbari6 | mobin6 | 20 |
| 15 | ghanbari7 | mobin7 | 21 |
+----+-----------+-----------+------+
7 rows in set (0.00 sec)
As you can see there are no duplicate entries in the table.

I am trying to import data from excel into MySQL using Python

I have created a small excel file to try this process
+----------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+ | S no | int(11) | NO | PI | NULL | | | Order | int(11)
| YES | | NULL | | | Price | int(11) | YES |
| NULL | | | comments | var char(45) | YES | | NULL
| |
+----------+-------------+------+-----+---------+-------+ 4 rows in set (1.21 sec)
This is the code I am using in python for the same
import xlrd import pymysql book =
xlrd.open_workbook(r'C:\Users\hp\Desktop\excel-python-mysql.xlsx')
sheet = book.sheet_by_index(0)
# Connect to the database
connection = pymysql.connect(host='localhost',
user='root',
password='*****',
db='trial',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
cursor = connection.cursor()
query = """INSERT INTO demo(Sno,Order,Price,Comments)VALUES(%d,%d,%d,%s)"""
for r in range(1,sheet.nrows):
Sno = sheet.cell(r,0).value
Order = sheet.cell(r,1).value
Price = sheet.cell(r,2).value
Comments = sheet.cell(r,3).value
values = (Sno,Order,Price,Comments)
cursor.execute(query,values)
cursor.close()
connection.commit()
connection.close()
but I am facing error stating "%d format: a number is required, not str" I want to move the data to MySQL for further use it at Metabase.

Python Mysql insert working on Windows not on Linux

So I'm trying to get prices of crypto currencies via an API every N seconds and store them in a MySQL DB in Python 3. So far I have written this code.
import requests
import pymysql
import json
import threading
def addEthPrice():
threading.Timer(11, addEthPrice).start()
url = 'https://min-api.cryptocompare.com/'
urlPrice = 'https://min-api.cryptocompare.com/data/pricemulti?fsyms=BTC,ETH&tsyms=USD,EUR,GBP'
login_data = dict(login='*', password='*')
session = requests.session()
r = session.post(urlPrice, data=login_data)
print("Response Code: ", r, "\n")
data = json.loads(r.content.decode())
conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='*', db='eth')
sql = "INSERT INTO price (date, ethGBP, ethUSD, ethEUR) VALUES(UTC_TIMESTAMP, %s, %s, %s)"
params = (str(data['ETH']['GBP']),
str(data['ETH']['USD']),
str(data['ETH']['EUR']))
try:
with conn.cursor() as c:
res = c.execute(sql, params)
print(params)
print("mysql response: ", res)
finally:
conn.close()
if __name__ == "__main__":
addEthPrice()
Now this code runs fine on Windows and stores it in the DB here is the description of the table for Windows:
+--------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------------+------+-----+---------+-------+
| date | timestamp | YES | | NULL | |
| ethGBP | decimal(12,8) | YES | | NULL | |
| ethUSD | decimal(12,8) | YES | | NULL | |
| ethEUR | decimal(12,8) | YES | | NULL | |
+--------+---------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
And here is the description for the Linux table:
+--------+---------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------------+------+-----+-------------------+-----------------------------+
| date | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| ethGBP | decimal(12,8) | YES | | NULL | |
| ethUSD | decimal(12,8) | YES | | NULL | |
| ethEUR | decimal(12,8) | YES | | NULL | |
+--------+---------------+------+-----+-------------------+-----------------------------+
4 rows in set (0.04 sec)
I have used the same syntax to create both the tables but the Linux one has added parameters.
Here's my question, When I run these script the data gets added fine to the WAMP MySQL but not to the Linux MySQL version, Why is this and how can I make it so it works on both.
Linux version 5.7.18-0ubuntu0.16.04.1
Windows version MySQL5.7.14
Thanks.

Having trouble insert data to table with default values

I have a table that has 4 attributes.
+--------------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| url | varchar(255) | YES | | NULL | |
| mail | varchar(255) | YES | | NULL | |
| date_entered | timestamp | NO | | CURRENT_TIMESTAMP | |
| active | tinyint(1) | NO | | 1 | |
+--------------+--------------+------+-----+-------------------+----------------+
Now i want to insert only the data_entered and other attributes to get default values.
I'm doing it for the id field which I need to be exact to another id I insereted to different table.
this is the code:
tx.execute(\
"insert into company_career (date_entered) "
"values (%s)",
(time.time())
)
This is the error:
query = query % db.literal(args)
exceptions.TypeError: not all arguments converted during string formatting
How to fix it?
Try this:
tx.execute(\
"insert into company_career (date_entered) "
"values (FROM_UNIXTIME('%s'))",
(time.time())
)
when you are providing values into a insert query dont forget to enclode it in commas
"insert into company_career (date_entered) values ('%s')"
I did manage to insert with: insert into company(url,mail,date_entered) values("","","now");

Categories

Resources