Why isn't insert/update working on unique key? - python

I wrote a function to take a list of lists and insert into my database table, however, if there is a duplicate key, one of the columns is to update. What am I doing wrong?
def insert_or_update(self, data):
try:
self.cursor.executemany('''insert into landing_pages (profile_id, landing_page, keyword_count, unique_key)
values (%s, %s, %s, %s) on duplicate key update keyword_count =values(keyword_count)''', (data))
self.db.commit()
return self.cursor.lastrowid
except Exception as e:
self.db.rollback()
# Rollback in case there is any error
return e
finally:
self.db.close()
Update:
Sorry, forgot to mention the actual issue (been working for all day). It doesn't seem to be updating, instead, it just inserts the data again.
For the unique key, I'm actually creating a salted hash, this is from the profile_id and landing_page columns; the hash is passed into the unique_key column.
My table looks like this:
+---------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+---------------+------+-----+---------+----------------+
| id | mediumint(9) | NO | PRI | NULL | auto_increment |
| profile_id | int(11) | YES | | NULL | |
| landing_page | varchar(2083) | YES | | NULL | |
| keyword_count | int(11) | YES | | NULL | |
| unique_key | varchar(200) | YES | UNI | NULL | |
+---------------+---------------+------+-----+---------+----------------+

Assuming keyword_count is an int, could you change the following in your query:
update keyword_count =values(keyword_count)
to
update keyword_count = <value>

I think your problem in table is self explanatory
your key is id
values you are inserting are
profile_id, landing_page, keyword_count, unique_key
none of which clash with your key
On update that there was unique key:
http://sqlfiddle.com/#!9/881082/1

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.

Cannot add or update a child row: a foreign key constraint fails on a Django generated MySQL table

I am working on a django based project which created two tables table1 and table2 with a foreign key from table2 to table1. I need to insert some values manually into table2. On trying to do so in MySQL I get the constraint failure error. I checked thoroughly, corresponding entries required for a foreign key constraint already exist in table1. I looked into some previous questions on SO but could not find an appropriate solution.
Table1 Schema:
+------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| email | varchar(100) | NO | | NULL | |
Table 2:
+-------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| km | varchar(1000) | YES | | NULL | |
| owner_id | int(11) | NO | MUL | NULL | |
| receiver_id | int(11) | NO | MUL | NULL | |
+-------------+---------------+------+-----+---------+----------------+
The insert statement insert into crest_recipient values(id,owner_id=5,receiver_id=5,km="hello world");
or similar ones fail with the exact error as
Cannot add or update a child row: a foreign key constraint fails
(crest.crest_recipient CONSTRAINT
crest_recipient_owner_id_4943116a1387be04_fk_crest_user_id FOREIGN
KEY (owner_id) REFERENCES crest_user (id))
You are attempting to update or insert a row in crest.crest_recipient table, a value in column owner_id
that does not exist in crest_user column id
Edit
make it look like this
insert crest_recipient (km,owner_id,receiver_id) values ('test',5,1)
'test',5,1 are whatever you want.
Skip the id column. Don't specify it, don't supply the value for it. It is an auto_increment PK most likely (basically there is nothing else it can be). The db engine chooses it for you. Specifying it will just screw things up 99% of the time.
Focus on parameter 2 for now (the 5)
You are trying to insert a row in child table crest_recipient which does not exist in parent table crest_user.
So first insert corresponding row in master table then you can insert in child table.

Importing csv file in mysql

I have a database with tables: person, player, coach, and team. All the tables have an auto-increment id field as the primary key. Person has id, firstname, lastname. Player and coach both have the id field, as well as person_id and team_id as foreign keys to tie them to a team.id or person.id field in the other tables.
I have one master csv file, from that I want import all the values in MySql different tables with ids.
And I want to check the value also in the data base. If the value is in database then do not import that value.
I have used CSV parsing and indexing function. But I am not able to do that. Can any one help me in that
My sql table below
mysql> describe person;
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| firstname | varchar(30) | NO | | NULL | |
| lastname | varchar(30) | NO | | NULL | |
+-----------+-------------+------+-----+---------+----------------+
mysql> describe player;
+-----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| person_id | int(11) | NO | MUL | NULL | |
| team_id | int(11) | NO | MUL | NULL | |
+-----------+---------+------+-----+---------+----------------+
mysql> describe team;
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| teamname | varchar(25) | NO | | NULL | |
| location | varchar(40) | NO | | NULL | |
| city | varchar(25) | NO | | NULL | |
| state | varchar(2) | NO | | NULL | |
| venue | varchar(35) | NO | | NULL | |
| league_id | int(11) | NO | MUL | NULL | |
+-----------+-------------+------+-----+---------+----------------+
My Csv file is
First Name Last Name teamname Location city state |venue
abc cdf india csv bng kar abc
After importing
I have a database with tables: person, player, coach, and team. All the tables have an auto-increment id field as the primary key. Person has id, firstname, lastname. Player and coach both have the id field, as well as person_id and team_id as foreign keys to tie them to a team.id or person.id field in the other tables.
I have one master csv file, from that I want import all the values in MySql different tables with ids.
And I want to check the value also in the data base. If the value is in database then do not import that value.
I have used CSV parsing and indexing function. But I am not able to do that. Can any one help me in that
My sql table below
mysql> describe person;
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| firstname | varchar(30) | NO | | NULL | |
| lastname | varchar(30) | NO | | NULL | |
+-----------+-------------+------+-----+---------+----------------+
mysql> describe player;
+-----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| person_id | int(11) | NO | MUL | NULL | |
| team_id | int(11) | NO | MUL | NULL | |
+-----------+---------+------+-----+---------+----------------+
mysql> describe team;
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| teamname | varchar(25) | NO | | NULL | |
| location | varchar(40) | NO | | NULL | |
| city | varchar(25) | NO | | NULL | |
| state | varchar(2) | NO | | NULL | |
| venue | varchar(35) | NO | | NULL | |
| league_id | int(11) | NO | MUL | NULL | |
+-----------+-------------+------+-----+---------+----------------+
My Csv file is
First Name Last Name teamname Location city state |venue
abc cdf india csv bng kar abc
After importing
id First Name Last Name teamname Location city state |venue coment
1 1 1 1 1 1 1 abc abc
I am trying with some small code
# initialize with empty ints and dicts
name,cities,countries,states=[],[],[],[]
with open('ind.csv','rb') as csvfile:
reader = csv.reader(csvfile, delimiter=',')
reader.next() #skip header
for row in reader:
name.append(row[0])
cities.append(row[2])
states.append(row[3])
countries.append(row[4])
cl = list(set(countries))
sl = list(set(states))
citl = list(set(cities))
inf1 = list(set(name))
with open('countries.csv','w') as cfile:
writer = csv.writer(cfile, delimiter=',')
writer.writerow(['country_id','name'])
for i,x in enumerate(cl):
writer.writerow([i,x])
with open('state.csv','w') as cfile:
writer = csv.writer(cfile, delimiter=',')
writer.writerow(['state_id','country_id','state'])
for i,x in enumerate(sl):
writer.writerow([i,x,cl.index(countries[states.index(x)])])
with open('cities.csv','w') as cfile:
writer = csv.writer(cfile,delimiter=',')
writer.writerow(['city_id','city','st_id','country_id'])
for i,x in enumerate(citl):
writer.writerow([i,x,sl.index(states[cities.index(x)]),
cl.index(countries[cities.index(x)])
])
with open('inf123.csv','w') as cfile:
writer = csv.writer(cfile,delimiter=',')
writer.writerow(['Name_id', 'Name','city_id','st_id','country_id'])
for i,x in enumerate(inf1):
writer.writerow([i,x,
citl.index(cities[name.index(x)]),
sl.index(states[name.index(x)]),
cl.index(countries[name.index(x)])
])
import MySQLdb
import csv
mydb = MySQLdb.connect(host="localhost", # The Host
user="root", # username
passwd="root", # password
db="abcm") # name of the data base
cursor = mydb.cursor()
csv_data = csv.reader(file('countries.csv'))
for row in csv_data:
cursor.execute('INSERT INTO country(id, \
name )' \
'VALUES("%s", "%s")',
row)
#close the connection to the database.
mydb.commit()
cursor.close()
print "Done"
cursor = mydb.cursor()
csv_data = csv.reader(file('state.csv'))
for row in csv_data:
cursor.execute('INSERT INTO state(id, \
country, name )' \
'VALUES("%s", "%s", "%s")',
row)
#close the connection to the database.
mydb.commit()
cursor.close()
print "Done"
I have one master csv file, from that I want import all the values in
MySql different tables with ids.
This is not possible because the import routine doesn't know where you want to put the data.
If your master csv file contained a column containing the table name you could then
import your csv file into a temporary
use different sql statements to move the data into the appropriate tables

Python MySQLdb: combine 2 tables,select data as dict. I am confused about the dict's key

I have two tables:user and post
and the structures of them are:
post:
+---------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | char(30) | YES | | NULL | |
| user_id | int(11) | YES | | NULL | |
+---------+----------+------+-----+---------+----------------+
user:
+---------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+----------+------+-----+---------+----------------+
| user_id | int(11) | NO | PRI | NULL | auto_increment |
| name | char(30) | YES | | NULL | |
| email | char(30) | YES | | NULL | |
+---------+----------+------+-----+---------+----------------+
i get this:(keys of data dict)
['post.user_id', 'user_id', 'name', 'email', 'post.name', 'id']
my python code is:
import MySQLdb
import MySQLdb.cursors
con = MySQLdb.connect(user = "root", passwd = "123456", db = "mydb", cursorclass=MySQLdb.cursors.DictCursor)
cur = con.cursor()
cur.execute("select * from user, post where user.user_id = post.user_id")
print cur.fetchone().keys()
but,why the keys of data dict is that? thanks. My English is not so well,excuse me
When you select *, you ask for all columns in both user and post. Since user and post have columns with overlapping names, the tablename is added before a few of them, to create unique keys.
I'm not sure what you were expecting, but you can explicitly control the keys you get by giving the columns aliases:
"select user.user_id as user_id, post.name as post_name, user.name as user_name ..."

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