Related
I tried to insert data to the database using python but I got a MySQLdb error
self.cur.execute('''
INSERT INTO book(book_name, book_desc, book_code, book_category, book_author, book_publisher, book_price)
VALUES(%s, %s, %s, %s, %s, %s, %s)
''', (book_title, book_desc, book_code, book_category, book_author, book_publisher, book_price, ))
self.db.commit()
I got this error:
MySQLdb._exceptions.OperationalError: (1366, "Incorrect integer value: '' for column 'book_code' at row 1")
According to the values you shared in the comments, book_code is a string, which is incompatible with the int value in the database. You could overcome this issue by converting it to an int:
self.cur.execute('''
INSERT INTO book(book_name, book_desc, book_code, book_category, book_author, book_publisher, book_price)
VALUES(%s, %s, %s, %s, %s, %s, %s)
''', (book_title, book_desc, int(book_code), book_category, book_author, book_publisher, book_price, ))
Basically I have some JSON data that I want to put in a MySQL db and to do this I'm trying to get the contents of a dictionary in a cursor.execute method. My code is as follows:
for p in d['aircraft']:
with connection.cursor() as cursor:
print(p['hex'])
sql = "INSERT INTO `aircraft` (`hex`, `squawk`, `flight`, `lat`, `lon`, `nucp`, `seen_pos`, " \
"`altitude`, `vert_rate`, `track`, `speed`, `messages`, `seen`, `rssi`) " \
"VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s )"
cursor.execute(sql, (p['hex'], p['squawk'], p['flight'], p['lat'], p['lon'], p['nucp'], p['seen_pos'], p['altitude'], p['vert_rate'], p['track'], p['speed'], p['messages'], p['seen'], p['rssi']))
print('entered')
connection.commit()
The issue is that any value in the dictionary can be null at any time and I need to find out how to handle this. I've tried to put the code in a try catch block and 'pass' whenever a KeyError exception is raised but this means a record is completely skipped when it has a null value. I've also tried to write a load of if blocks to append a string with the value of the dictionary key but this was pretty useless.
I need to find a way to put a dictionary in my db even if it contains null values.
You can use the dict.get() method, or construct a defaultdict that returns None for missing keys:
import collections
keys = ['hex', 'squawk', 'flight', 'lat', 'lon', 'nucp', 'seen_pos',
'altitude', 'vert_rate', 'track', 'speed', 'messages', 'seen',
'rssi']
for p in d['aircraft']:
with connection.cursor() as cursor:
sql = "INSERT INTO `aircraft` (`hex`, `squawk`, `flight`, `lat`, `lon`, `nucp`, `seen_pos`, " \
"`altitude`, `vert_rate`, `track`, `speed`, `messages`, `seen`, `rssi`) " \
"VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s )"
# Could also use a defaultdict
cursor.execute(sql, tuple(p.get(key) for key in keys))
print('entered')
connection.commit()
For more examples using dict.get(), see this answer: https://stackoverflow.com/a/11041421/1718575
This assumes that SQL will do the right thing when None is provided. If you want to use a string 'NULL', you can supply that as the second argument to dict.get().
Can anyone help, I have no idea why it keeps returing the error
ERROR: Not enough arguments for format string
It's reading from a csv where the headers are named Property ID, Reference Number etc. The only difference is the addition of the _ in the table column names.
Here is my script for reference:
import csv
import pymysql
mydb = pymysql.connect(host='127.0.0.1', user='root', passwd='root', db='jupix', unix_socket="/Applications/MAMP/tmp/mysql/mysql.sock")
cursor = mydb.cursor()
with open("activeproperties.csv") as f:
reader = csv.reader(f)
# next(reader) # skip header
data = []
for row in reader:
cursor.executemany('INSERT INTO ACTIVE_PROPERTIES(Property_ID, Reference_Number,Address_Name,Address_Number,Address_Street,Address_2,Address_3,Address_4,Address_Postcode,Owner_Contact_ID,Owner_Name,Owner_Number_Type_1,Owner_Contact_Number_1,Owner_Number_Type_2,Owner_Contact_Number_2,Owner_Number_Type_3,Owner_Contact_Number_3,Owner_Email_Address,Display_Property_Type,Property_Type,Property_Style,Property_Bedrooms,Property_Bathrooms,Property_Ensuites,Property_Toilets,Property_Reception_Rooms,Property_Kitchens,Floor_Area_Sq_Ft,Acres,Rent,Rent_Frequency,Furnished,Next_Available_Date,Property_Status,Office_Name,Negotiator,Date_Created)''VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)', row)
mydb.commit()
cursor.close()
print"Imported!"
The error is happening because you have 37 columns that you are trying to insert data into, but 38 inputs that you are sending to the database i.e %s. Therefore you are telling the cursor to send a piece of data to the database but the cursor does not know where to insert the data into. You either forgot to include a column in your INSERT INTO statement, or have an extra %s in your statement.
Therefore you need to remove one of the %s in your SQL statement, or add a column in your database to send the last piece of data into.
When you have a large number of columns, it can be a challenge to make sure you have one %s for each column. There's an alternative syntax for INSERT that makes this easier.
Instead of this:
INSERT INTO ACTIVE_PROPERTIES(Property_ID, Reference_Number,
Address_Name, Address_Number, Address_Street, Address_2, Address_3,
Address_4, Address_Postcode, Owner_Contact_ID, Owner_Name,
Owner_Number_Type_1, Owner_Contact_Number_1, Owner_Number_Type_2,
Owner_Contact_Number_2, Owner_Number_Type_3, Owner_Contact_Number_3,
Owner_Email_Address, Display_Property_Type, Property_Type,
Property_Style, Property_Bedrooms, Property_Bathrooms, Property_Ensuites,
Property_Toilets, Property_Reception_Rooms, Property_Kitchens,
Floor_Area_Sq_Ft, Acres, Rent, Rent_Frequency, Furnished,
Next_Available_Date, Property_Status, Office_Name, Negotiator,
Date_Created)
VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s)
Try the following, to make it easier to match up columns with %s parameters, so you don't miscount:
INSERT INTO ACTIVE_PROPERTIES
SET Property_ID = %s,
Reference_Number = %s,
Address_Name = %s,
Address_Number = %s,
Address_Street = %s,
Address_2 = %s,
Address_3 = %s,
Address_4 = %s,
Address_Postcode = %s,
Owner_Contact_ID = %s,
Owner_Name = %s,
Owner_Number_Type_1 = %s,
Owner_Contact_Number_1 = %s,
Owner_Number_Type_2 = %s,
Owner_Contact_Number_2 = %s,
Owner_Number_Type_3 = %s,
Owner_Contact_Number_3 = %s,
Owner_Email_Address = %s,
Display_Property_Type = %s,
Property_Type = %s,
Property_Style = %s,
Property_Bedrooms = %s,
Property_Bathrooms = %s,
Property_Ensuites = %s,
Property_Toilets = %s,
Property_Reception_Rooms = %s,
Property_Kitchens = %s,
Floor_Area_Sq_Ft = %s,
Acres = %s,
Rent = %s,
Rent_Frequency = %s,
Furnished = %s,
Next_Available_Date = %s,
Property_Status = %s,
Office_Name = %s,
Negotiator = %s,
Date_Created = %s;
It's not standard SQL, but it's supported by MySQL. It does the same thing internally, it's just more convenient syntax, at least when you're inserting a single row at a time.
a simple example. also you can manipulate it for your needs.
myDict = {'key-1': 193699, 'key-2': 206050, 'key-3': 0, 'key-N': 9999999}
values = ', '.join(f"'{str(x)}'" for x in myDict.values())
columns = ', '.join(myDict.keys())
sql = f"INSERT INTO YourTableName ({columns}) VALUES ({values});"
conn = pymysql.connect(autocommit=True, host="localhost",database='DbName', user='UserName', password='PassWord',)
with conn.cursor() as cursor:
cursor.execute(sql)
I'm trying to insert many rows in MySQL database and for some reason I'm always getting this error.
I have already tried the solutions present in this topic and nothing works.
TypeError: not enough arguments for format string
My Code:
cursor = db.cursor()
row = (date, timetoserve, ipcliente, cacheCode, bytesint, method,\
url.scheme, url.hostname, url.port, url.path, auth, route[0], route[1], contentType)
items.append(row)
if Inputs % 100 == 0:
sql = "INSERT INTO LogTbl \
(DateConnection, TimeToServe, ClientIP, CacheCode, Bytes, Method,\
RequestProtocol, RequestIP, RequestPort, RequestFolder, Auth, RouteLeft, RouteRight, ContentType)\
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
cursor.executemany(sql, items)
items = []
db.commit()
I try to add data to the database (use psycopg2.connect):
cand = Candidate('test', datetime.now(), 'test#test.t', '123123', "21", 'test', 'test', 'test', datetime.now(), "1", "1", 'test', 'M', "18", "2", "2")
db.addCandidate(cand)
my function add:
def addCandidate(self, candidate):
with self.connection.cursor() as cursor:
cursor.execute("""INSERT INTO candidate ( name, pub_date, email, tel, age, proff, href, city, last_update, called_count, status, comment, sex, recrut_id, vacancy_id, level)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", (candidate.name, candidate.pub_date, candidate.email, candidate.tel,
candidate.age, candidate.proff, candidate.href, candidate.city, candidate.last_update, candidate.called_count, candidate.status, candidate.comment, candidate.sex, candidate.recrut_id,
candidate.vacancy_id, candidate.level))
self.connection.commit()
tried wrapping data in str, but nothing has changed.
in pymysql.connect work fine
I can't tell for sure because I don't know the types of your columns but it's plausible that your datetime object is not of the right format. You're sending in the datetime object not a string in the right date format. Try:
candidate.pub_date.isoformat()
or
candidate.pub_date.strftime("<proper_format">)
See http://strftime.org/ for format options. That may work for you.
In instead of execute do mogrify to check what exactly is being sent to the server:
print cursor.mogrify ("""
INSERT INTO candidate (
name, pub_date, email, tel, age, proff, href, city,
last_update, called_count, status, comment,
sex, recrut_id, vacancy_id, level
) VALUES (
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s
)""", (
candidate.name, candidate.pub_date, candidate.email,
candidate.tel, candidate.age, candidate.proff, candidate.href,
candidate.city, candidate.last_update, candidate.called_count,
candidate.status, candidate.comment, candidate.sex,
candidate.recrut_id, candidate.vacancy_id, candidate.level
)
)
I solved my problem, I wrote 15 '%s', instead of 16