I have tried hours to get around this but still cannot make it to work properly. I am using scrapy to scrape data from a website and then trying to insert that into MySQL database. Here is my database code:
import MySQLdb
class Database:
host = 'localhost'
user = 'root'
password = 'test123'
db = 'scraping_db'
def __init__(self):
self.connection = MySQLdb.connect(self.host, self.user, self.password, self.db,use_unicode=True, charset="utf8")
self.cursor = self.connection.cursor()
def insert(self, query,params):
try:
self.cursor.execute(query,params)
self.connection.commit()
except Exception as ex:
self.connection.rollback()
def __del__(self):
self.connection.close()
Here is my pipeline code where I am making insert query and passing to the above class' insert method:
from con import Database
class LinkPipeline(object):
def __init__(self):
self.db=Database()
def process_item(self, item, spider):
query="""INSERT INTO links (title, location,company_name,posted_date,status,company_id,scraped_link,content,detail_link,job_id) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s,%s)"""
params=(item['title'], item['location'], item['company_name'], item['posted_date'], item['status'], item['company_id'], item['scraped_link'], item['content'], item['detail_link'],item['job_id'])
self.db.insert(query,params)
return item
This totally works fine on my local machine. But on server I get following error:
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 \')
When I print the params and query from exception block I have this:
query variable:
INSERT INTO links (title, location,company_name,posted_date,status,company_id,scraped_link,content,detail_link,job_id) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s,%s)
params variable:
((u'Account Leader, Sr',), (u'Sydney',), (u'\n Halliburton',), (datetime.datetime(2018, 4, 9, 21, 55, 46, 789575),), ('Pending',), ([u'0e4554ac6dcff427'],), (u'https://www.site.com.au/rc/clk?jk=3f41218887882940&fccid=0e4554ac6dcff427&vjs=3',), 'Job Content', 'https://jobs.halliburton.com/job/Account-Leader%2C-Sr-IS/437741300/?feedId=162400', ([u'3f41218887882940'],))
I feel the the tuple data is the culprit of MySQL string breaking somewhere due to quotes. But I am very new to Python not sure I checked in another question on SO to follow this syntax to insert into MySQL database i.e:
self.db.insert(query,params)
The above code works fine on my local machine but fails on server. Please guide me in right direction.
Thank you very much!
It very much looks like the tuple encapsulation is your issue. What is the output of:
print( repr( item['location'] ))
That's "print the (coder's) representation of item['location']" (rather than trying to be smart about printing.
>>> print( repr( item['location'] ))
('Sydney',) # A tuple, 1-long, containing a string
>>> print( repr( item['location'] ))
'Sydney' # A string
If it's the first, then your passed data structure inside of item apparently has an extra layer of encapsulation for which your code does not account. The quick and dirty approach to get you up and running:
def process_item(self, item, spider):
query="""INSERT INTO links (title, location,company_name,posted_date,status,company_id,scraped_link,content,detail_link,job_id) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s,%s)"""
params=(item['title'][0], item['location'][0], ...
self.db.insert(query,params)
return item
Note that this is hardly a robust solution, API-wise: what happens if one of those embedded tuples is zero length? (Hint: Exception). I've also not filled out the rest, because it looks like you have some elements in item that are not encapsulated at all, and others which are doubly encapsulated.
Additionally, you may have some encoding errors with your data after this as some of your elements are unicode and others are not. For example:
(u'Sydney',) ... ('Pending',)
You may want to check exactly what your schema requires.
Related
I´m quiet new to Python and trying my first own projects. At the moment I´m struggeling with an SQL insert of a dataframe to a Postgres database with placeholders for the values. I have one Python Script (database_config) which creates the database object and also the methods like execute(), which I want to call in my main script.
When I try to do the insert with an database connection/cursor which is generated in the main script it works well. But when I try to call the execute() method from the database_config script with the same query-string I get the following error message:
"FEHLER: Syntaxfehler bei »%«
LINE 19: VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, ..."
The database-config looks like:
import os
import psycopg2
# password for the database from an environment variable
db_pw = os.environ.get('DB_PASS')
conn_str = "host=localhost user=postgres dbname=nfl_scores_bets password={}".format(db_pw)
class MyDatabase():
def __init__(self):
self.conn = psycopg2.connect(conn_str)
self.cur = self.conn.cursor()
self.conn.set_session(autocommit=True)
def query_func(self, query, params=None):
try:
self.cur.execute(query)
except psycopg2.Error as e:
print(e)
The insert string and the method call from the main script are:
scores_bets_table_insert = ("""INSERT INTO scores_bets (
schedule_date,
schedule_season,
schedule_week,
schedule_playoff,
team_home,
score_home,
score_away,
team_away,
team_favorite_id,
spread_favorite,
over_under_line,
stadium_name,
stadium_neutral,
weather_temperature,
weather_wind_mph,
weather_humidity,
weather_detail)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
""")
# works fine, if I create the datbase connection in this main script
for i, row in scores_bets.iterrows():
cur.execute(scores_bets_table_insert, list(row))
# doesn´t work when I do the insert with the method from the database_config script
db =MyDatabase()
for i, row in scores_bets.iterrows():
db.query_func(scores_bets_table_insert, list(row))
Till now I couldn´t figured out what creates the syntax-error or what is the diffenrence between executing the same query string with the ursor from the same script or calling the execute() method from the other script. I couldn´t find the reason in the psycopg2 documentation, hopefully some one of you see the error or can give me a hint what I'm doing wrong.
You dont have to write your sql manually.
Pandas comes with a to_sql method. Try this:
scores_bets.to_sql('scores_bets', db.conn, if_exists='append', index=False)
Note: Make sure the columns in your DataFrame have the same name as your column in your database.
I'm struggling to insert or retrive data from database I tried and I watched many tutorials but every time it stops in cur.execute(). i found problem is in the value like self.FirstNmae.text() funtion stop here
def SignupFunction(self):
try:
connection = pymysql.connect(host=cr.host, user=cr.user, password=cr.password, database=cr.database)
cur = connection.cursor()
cur.execute("insert into users (FirstNmae , LastName, Email,Password , Confirm_Paswword ,Answer) value( %s, %s, %s, %s, %s, %s)",
(
self.FirstNmae.text(),
self.LastName.text(),
self.Email.text(),
self.Password.text(),
self.Confirm_Paswword.text(),
self.Answer.text()
))
connection.commit()
connection.close()
self.labelResult.setText("Data Inserted ")
except Exception as e:
self.labelResult.setText("Error Inserting Data")
hello friend i'm not able to comment so i will post as answer from your code you are a new developer , your function is good there are no problem in it i think that the problem is in you database look at the database if you are missed something or you mess write attributes like FirstNmae
I am trying solve problem with quotes in my sql queries. I know that many questions were asked on stackoverflow. But no one worked for me. May be because I am using other framework (pyMySQL) for sql connection. I tried parameterized mysql query:
conn = pymysql.connect(host ='host', user='user', passwd='user', db='db', charset='utf8mb4')
cur = conn.cursor()
cur.execute("USE db")
cur.execute("UPDATE table SET callback_data = %s, message = %s, photo = %s, location = %s, first_name_last_name = %s WHERE user_id=%s",
(callback_data, message, photo, location, first_name_last_name, user_id))
cur.connection.commit()
cur.close()
conn.close()
But I always get error with %s (error message: expected, got %s). My python version is 3.6.1. How I can escape quotes in my sql query? Thanks.
First, as Ilja sayed you have to use backticks for mysql reserved words.
Then for text/varchar fields you can use json dumps:
import json
[...]
cur.execute("UPDATE `table` SET callback_data = %s, message = %s, photo = %s, location = %s, first_name_last_name = %s WHERE user_id=%s", % (
json.dumps(callback_data),
json.dumps(message),
json.dumps(photo),
json.dumps(location),
json.dumps(first_name_last_name),
json.dumps(user_id)
)
ok
I am sending a query to my mysql server somthing like this
INSERT INTO accesslist (user, ip, sshid, status) VALUES ("root", "138.117.37.88", "1335", "Failed")
for it i wrote my query as
query = ('INSERT INTO %s (user, ip, sshid, status) VALUES (%s, %s, %s, %s)')
data_entry = (tablename, user, ip, sshid, status)
but what it is doing is it is adding quotes around tablename and mysql is throwing an error for that. It is sending as
INSERT INTO "accesslist" (user, ip, sshid, status) VALUES ("root", "138.117.37.88", "1335", "Failed")
so how can i remove the quotes around my tablename?
If i put a static tablename then it is working fine.
Your solution seems correct. Not to digress, but I recommend you to use str.format as it provides more options and support named kwargs. Besides it is a newer and recommended approach.
Tutorial
sorry if you consider as repost, quite simple code and i suspect also a trivial error here, but can't move forward:
import whois
import MySQLdb
db = MySQLdb.connect(host="localhost", user="root", passwd="pass", db="whois")
cur = db.cursor()
wi = whois.whois("google.com")
cur.execute("""INSERT INTO wrec (dname, wfull, dns) VALUES (%s, %s, %s)""") , (wi.domain_name, wi.text, wi.name_servers)
ends up in:
_mysql_exceptions.ProgrammingError: (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 '%s, %s, %s)' at line 1")
as said, suspecting trivial error. any suggestions? thanks a lot in advance
You placed the fetched Whois variables outside the execute function!
Change:
cur.execute("""INSERT INTO wrec (dname, wfull, dns) VALUES (%s, %s, %s)""") , (wi.domain_name, wi.text, wi.name_servers)
To:
cur.execute("""INSERT INTO wrec (dname, wfull, dns) VALUES (%s, %s, %s)""", (wi.domain_name, wi.text, wi.name_servers))
Edit:
And don't forget to add:
db.commit()
at the end of the script.