Adding Items on 2 tables in MYSQL database inside pipeline using Scrapy - python

Hi I am trying to add 2 tables in my MYSQL database I successfully added the 2 tables but the separated items like itemA and itemB is not added on Database
If I remove the itemB, ItemA works fine and added on table1, if 2 tables I always got this error
"NameError: name 'items_f21' is not defined"
Any Idea please?
Here's my code
sales_item_spider.py
def parse_1(self, response):
item = GpdealsSpiderItem_hm()
for product_item_hm in response.css('li.product-item'):
hm_title = product_item_hm.css('h3.item-heading a.link::text').extract_first()
hm_regular_price = product_item_hm.css('strong.item-price span.price.regular::text').extract_first()
hm_sale_price = product_item_hm.css('strong.item-price span.price.sale::text').extract_first()
hm_photo_url = product_item_hm.css('.image-container img::attr(data-src)').extract_first()
hm_description_url = product_item_hm.css('h3.item-heading a::attr(href)').extract_first()
item['hm_title'] = hm_title
item['hm_regular_price'] = hm_regular_price
item['hm_sale_price'] = hm_sale_price
item['hm_photo_url'] = hm_photo_url
item['hm_description_url'] = hm_description_url
yield item
def parse_2(self, response):
items_f21 = GpdealsSpiderItem_f21()
for product_item_forever in response.css('div.pi_container'):
f21_title = product_item_forever.css('p.p_name::text').extract_first()
f21_regular_price = product_item_forever.css('span.p_old_price::text').extract_first()
f21_sale_price = product_item_forever.css('span.p_sale.t_pink::text').extract_first()
f21_photo_url = product_item_forever.css('img::attr(data-original)').extract_first()
f21_description_url = product_item_forever.css('a.item_slider.product_link::attr(href)').extract_first()
items_f21['f21_title'] = f21_title
items_f21['f21_regular_price'] = f21_regular_price
items_f21['f21_sale_price'] = f21_sale_price
items_f21['f21_photo_url'] = f21_photo_url
items_f21['f21_description_url'] = f21_description_url
yield items_f21
pipelines.py
def create_table(self):
self.curr.execute("""DROP TABLE IF EXISTS saleitems_hm""")
self.curr.execute("""create table saleitems_hm(
hm_title text,
hm_regular_price text,
hm_sale_price text,
hm_photo_url text,
hm_description_url text
)""")
self.curr.execute("""DROP TABLE IF EXISTS saleitems_f21""")
self.curr.execute("""create table saleitems_f21(
f21_title text,
f21_regular_price text,
f21_sale_price text,
f21_photo_url text,
f21_description_url text
)""")
def process_item(self, item, spider):
self.store_db(item)
return item
def store_db(self, item):
self.curr.execute("""insert into saleitems_hm values (%s, %s, %s, %s, %s)""", (
item['hm_title'],
item['hm_regular_price'],
item['hm_sale_price'],
item['hm_photo_url'],
item['hm_description_url']
))
self.conn.commit()
self.curr.execute("""insert into saleitems_f21 values (%s, %s, %s, %s, %s)""", (
items_f21['f21_title'],
items_f21['f21_regular_price'],
items_f21['f21_sale_price'],
items_f21['f21_photo_url'],
items_f21['f21_description_url']
))
self.conn.commit()

Your store_db uses a items_f21 variable, which is never defined before.
On store_db you should use only the item variable, and use the corresponding INSERT statement depending on the type of item it is:
def store_db(self, item):
if isinstance(item, GpdealsSpiderItem_hm):
self.curr.execute("""insert into saleitems_hm values (%s, %s, %s, %s, %s)""", (
item['hm_title'],
item['hm_regular_price'],
item['hm_sale_price'],
item['hm_photo_url'],
item['hm_description_url']
))
else:
self.curr.execute("""insert into saleitems_f21 values (%s, %s, %s, %s, %s)""", (
item['f21_title'],
item['f21_regular_price'],
item['f21_sale_price'],
item['f21_photo_url'],
item['f21_description_url']
))
self.conn.commit()

Related

python - Error entering data into the database

A new member has been registered in the database, but when entering the profile modification page and adding other information, it is registered in a new row and not in the same information as the registered member.
register new member :
def add_users(self):
add_fullname = self.line_fullname.text()
add_username = self.line_username.text()
add_Email = self.line_email.text()
add_password = self.line_password.text()
add_phone = self.line_telephon.text()
add_birthday = self.dateofbirth.text()
add_profession = self.line_profession.text()
add_Country = self.line_country.text()
add_keyone = self.keyone.text()
add_keytwo = self.keytwo.text()
add_newpassword = self.new_pwd.text()
self.cur.execute(''' SELECT add_username FROM users=add_username''')
data = self.cur.fetchall()
self.cur.execute(''' INSERT INTO users(add_fullname,
add_username, add_Email, add_password, add_phone,
add_birthday, add_profession, add_Country, add_keyone, add_keytwo, add_newpassword)
VALUE (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s ) ''',
(add_fullname, add_username, add_Email, add_password, add_phone, add_birthday,
add_profession, add_Country, add_keyone, add_keytwo, add_newpassword))
self.mysql_db.commit()
self.line_fullname.clear()
self.line_username.clear()
self.line_email.clear()
self.line_password.clear()
this code for fill profile :
def save_profil(self):
self.tabWidget.setCurrentIndex(6)
add_fullname = self.line_fullname.text()
add_Email = self.line_email.text()
add_phone = self.line_telephon.text()
add_birthday = self.dateofbirth.text()
add_profession = self.line_profession.text()
add_Country = self.line_country.text()
add_keyone = self.keyone.text()
add_keytwo = self.keytwo.text()
add_newpassword = self.new_pwd.text()
self.cur.execute(''' INSERT INTO users(add_fullname, add_Email, add_phone, add_birthday, add_profession,
add_Country, add_keyone, add_keytwo, add_newpassword)
VALUE (%s, %s, %s, %s, %s, %s, %s, %s, %s ) ''',
(add_fullname, add_Email,
add_phone, add_birthday, add_profession,
add_Country, add_keyone, add_keytwo, add_newpassword))
self.mysql_db.commit()
print("profil edited")
You should use UPDATE instead of INSERT in the "save_profil" function if the profile already exists.
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
You will also need to indicate which user should be updated in
WHERE condition
I would also advise you to read the user ID or another unique key you have defined in your table. So you can update the correct user.
Ex:
def save_profil(self):
self.tabWidget.setCurrentIndex(6)
add_fullname = self.line_fullname.text()
add_Email = self.line_email.text()
add_phone = self.line_telephon.text()
add_birthday = self.dateofbirth.text()
add_profession = self.line_profession.text()
add_Country = self.line_country.text()
add_keyone = self.keyone.text()
add_keytwo = self.keytwo.text()
add_newpassword = self.new_pwd.text()
query = "UPDATE users SET add_fullname=%s, add_Email=%s, add_phone=%s, add_birthday=%s, add_profession=%s, add_Country=%s, add_keyone=%s, add_keytwo=%s, add_newpassword= %s WHERE (UNIQUE_KEY = %s)"
data = (add_fullname, add_Email,add_phone, add_birthday, add_profession,add_Country, add_keyone, add_keytwo, add_newpassword, UNIQUE_KEY_VALUE)
self.cur.execute(query,data)
self.mysql_db.commit()
print("profil edited")
Note that UNIQUE_KEY and UNIQUE_KEY_VALUE are suggestions, you must define these values according to your model.
As I can see in the figure that shows the database, you can use the "id" to know which user should be updated.For this case, UNIQUE_KEY would be replaced by id, and UNIQUE_KEY_VALUE would be the user id that needs to be updated, in your example it would be 14, but you need to get that value inside your function, just like you got the other values.

TypeError: can only concatenate str (not "numpy.float64") to str Python/MYSQL

I'm writing a stock tracker app for myself with a python backend, i needed to add an update statement in and when i do the code no longer functions - I get the error, "TypeError: can only concatenate str (not "numpy.float64") to str."
The incert statements work fine and if i remove this it all works again. Any ideas where i am going wrong with this?
mycursor = mydb.cursor()
mycursor.execute("UPDATE stock_mains.user_stock SET user_stock1_price = '" + stock_live_price + "' WHERE user_id = 'da_mike' AND user_stock1 is NOT NULL")
mydb.commit()
if market_status == "REGULAR":
mycursor = mydb.cursor()
sql = "INSERT INTO stock_live (Stock_symbol, Stock_live_price, stock_datetime, stock_volume, stock_marketcap, stock_dayrange, stock_open, stock_previousclose) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)"
val = (arg, stock_live_price, timestamp, volume, marketcap, dayrange, openprice, previousclose)
mycursor.execute(sql, val)
mydb.commit()
stock_live_int = float(stock_live_price)
print(round(stock_live_int, 2))
elif market_status == "PRE":
stock_premarket_price = si.get_premarket_price(arg)
mycursor = mydb.cursor()
sql = "INSERT INTO stock_live (Stock_symbol, stock_premarket_price, stock_datetime, stock_volume, stock_marketcap, stock_dayrange, stock_open, stock_previousclose) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)"
val = (arg, stock_premarket_price, timestamp, volume, marketcap, dayrange, openprice, previousclose)
mycursor.execute(sql, val)
mydb.commit()
print(stock_premarket_price)
print(mycursor.rowcount, "record inserted.")
elif market_status == "POST":
stock_postmarket_price = si.get_postmarket_price(arg)
mycursor = mydb.cursor()
sql = "INSERT INTO stock_live (Stock_symbol, stock_aftermarket_price, stock_datetime, stock_volume, stock_marketcap, stock_dayrange, stock_open, stock_previousclose) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)"
val = (arg, stock_postmarket_price, timestamp, volume, marketcap, dayrange, openprice, previousclose)
mycursor.execute(sql, val)
mydb.commit()
print(stock_postmarket_price)
print(mycursor.rowcount, "record inserted.")
elif market_status == "CLOSED":
mycursor = mydb.cursor()
mycursor.execute("UPDATE stock_mains.user_stock SET user_stock1_price = '" + stock_live_price + "' WHERE user_id = 'da_mike' AND user_stock1 is NOT NULL")
mydb.commit()
print("Market is Closed")
stock_live_int = float(stock_live_price)
print(round(stock_live_int, 2))
time.sleep(0.1)
First of all, you should use prepared statements to avoid SQL injections. You can change your query to convert the float value to str:
mycursor = mydb.cursor()
query = "UPDATE stock_mains.user_stock SET user_stock1_price = %s WHERE user_id = 'da_mike' AND user_stock1 is NOT NULL"
mycursor.execute(query, (str(stock_live_price),))
mydb.commit()

mysql.connector in python / cursor in for-loop only working for first row of table

I have a table and I want to translate columns 'topic' and 'review' of a row and store the entire table with their translations into a new table. It seems that the for-loop doesn't iterate over all rows of the input table. Only the first row is stored into the new table. Why?
database = mysql.connector.connect(user='root', password='root', host='localhost', database='test')
DBcursor = database.cursor(buffered=True)
query = ("SELECT * FROM test_de")
DBcursor.execute(query)
for (id, user_name, date, country, version, score, topic, review, url) in DBcursor:
topic_trans = translate(topic, 'en')
review_trans = translate(review, 'en')
add_translation = ("INSERT INTO test_de_en(id, user_name, date, country, version, score, topic, review, url)"
"VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)")
translation_data = (id, user_name, date, country, version, score, topic_trans, review_trans, url)
DBcursor.execute(add_translation, translation_data)
database.commit()
DBcursor.close()
database.close()

Finding the value of an auto-increment field

I have a simple registration form which creates a new record in "Students" table:
cur = con.cursor()
query = "INSERT INTO students (Name, Address, Major, Phone, Email, Password) values (%s, %s, %s, %s, %s, %s)"
args = [name, address, major,phone, email, password]
cur.execute(query, args)
con.commit()
The column Id is auto-incremented, so in order to get the last Id, I select Max
query = "SELECT MAX(Id) FROM students;"
cur.execute(query)
id = cur.fetchone()[0]
It works in my little homework-project, but how would it be done in a heavy-loaded project, where there is a possibility of something being created before the select statement?
Use lastrowid attribute:
...
cur.execute(query, args)
id = cur.lastrowid

Inserting list items into database as separate entries

I have an input field that is basically a comma delimited string (i.e. something like "deniscm, toms, peters"). That information is sent via AJAX to my Python handler SaveQueryPage. What I want to do is parse this information as a list and then insert each entry into my database. My code is as follows, but it doesn't work unfortunately. Any suggestions?
Python code:
class SaveQueryPage(webapp2.RequestHandler):
def post(self):
user = users.get_current_user()
user_nickname = user.nickname()
query_name = self.request.get('queryName')
query_collab = self.request.get('queryCollab')
query_collaborators = re.split(r'\s*[,]\s*', query_collab.strip())
query_collaborators = query_collaborators.append(user_nickname)
query_collaborators = filter(None, query_collaborators)
conn = rdbms.connect(instance=_INSTANCE_NAME, database='queryInfo')
cursor = conn.cursor()
cursor.execute('INSERT INTO queries (userNickname, queryName) VALUES (%s, %s)', (user_nickname, query_name))
conn.commit()
for item in query_collaborators:
cursor = conn.cursor()
cursor.execute('INSERT INTO collaborators (queryName, userNickname) VALUES (%s, %s)', (query_name, item))
conn.commit()
conn.close()
I finally managed to get it working. Looks like the regular expression turned the items in the list to a unicode format, which was only caught when I added some logs. I also had an error in appending a string to the list. Thanks for the pointers! The code below now works for me:
class SaveQueryPage(webapp2.RequestHandler):
def post(self):
user = users.get_current_user()
user_nickname = user.nickname()
user_email = user.email()
query_name = self.request.get('queryName')
query_description = self.request.get('queryDescription')
query_collab = self.request.get('queryCollab')
logging.info('Data read for query_collab is %s', query_collab)
query_collab_re = re.split(r'\s*[,;]\s*', query_collab.strip())
logging.info('Data read for query_collab_re is %s', query_collab_re)
query_collab_decode = []
for item in query_collab_re:
item = str(item)
query_collab_decode.append(item)
logging.info('Data read for query_collab_decode is %s', query_collab_decode)
query_collab_decode.append(user_nickname)
logging.info('Data read for query_collab_append is %s', query_collab_decode)
query_collab_filter = filter(None, query_collab_decode)
logging.info('Data read for query_collab_filter is %s', query_collab_filter)
query_value = self.request.get('queryValue') # query_value
date_created = datetime.today()
date_lastupdated = datetime.today()
active_flag = "true"
random_id = random.randint(1000000000000, 9999999999999)
unique_query_id = user_nickname + "_" + str(random_id)
conn = rdbms.connect(instance=_INSTANCE_NAME, database='userPrefs')
cursor = conn.cursor()
cursor.execute('INSERT INTO queries (userNickname, queryName, queryDescription, queryValue, dateCreated, dateLastUpdated, activeFlag, uniqueId) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)', (user_nickname, query_name, query_description, query_value, date_created, date_lastupdated, active_flag, unique_query_id))
conn.commit()
try:
for item in query_collab_filter:
cursor = conn.cursor()
cursor.execute('INSERT INTO collaborators (uniqueId, userNickname) VALUES (%s, %s)', (unique_query_id, item))
conn.commit()
except:
logging.error('There was an error inserting the values into the collaborators table. query_collaborators =' + str(query_collaborators))
conn.close()

Categories

Resources