I am creating a dictionary in python - python

I want a structure like
var={userid:{bookid:rating,book2:rating,.....}}
I am not getting how to query it.
I am getting a structure like this:-
example:-
var={1:{101:2}}{1:{102:1}}
but I want
var={1:{101:2,102:1}}
I am fetching all the values of userid,bookid,ratings from database.
And also I would like to know how to access those records
Actually I am creating a recommender engine so I need to compare each user with every other user.Please if anyone can help me in this
Thankyou

To answer your first question on how to create such a structure. You can create a dictionary like this one by following lines:
a = {}
a[1] = {}
a[1][101] = 2
a[1][102] = 1
print a # output: {1: {101: 2, 102: 1}}
(It's actually a dictionary in a dictionary)
To answer your question how to access the results:
Here is a code example for accessing the results of your query.
import datetime
import mysql.connector
cnx = mysql.connector.connect(user='scott', database='employees')
cursor = cnx.cursor()
query = ("SELECT first_name, last_name, hire_date FROM employees "
"WHERE hire_date BETWEEN %s AND %s")
hire_start = datetime.date(1999, 1, 1)
hire_end = datetime.date(1999, 12, 31)
cursor.execute(query, (hire_start, hire_end))
for (first_name, last_name, hire_date) in cursor:
print("{}, {} was hired on {:%d %b %Y}".format(
last_name, first_name, hire_date))
cursor.close()
cnx.close()
(This example is taken from this page: https://dev.mysql.com/doc/connector-python/en/connector-python-example-cursor-select.html)
This could be helpful as well: https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html

Related

IndexError out of range on Python

I have a python code to insert data into my database. Here is the line:
query = 'insert into 1_recipe values({0})'. I used {0} to pass all data from my CSV file. It works perfectly before I use sys.argv in my code. Here is the new code :
import sys
nomor = sys.argv[1]
.....
query = "insert into {idnumber}_recipe values ({0})".format(idnumber = nomor)
query = query.format(','.join(['%s'] * len(data)))
.....
When I run this code, always back with this error :
'query = "insert into {idnumber}_recipe values ({0})".format(idnumber = nomor)
IndexError: Replacement index 0 out of range for positional args tuple'
How to fix it? Thanks.
Update:
I already found the answer. Thank you
You are only passing one argument to the format() function:
.format(idnumber = nomor)
The format function doesn't have a value to give to the ({0}) part of the formatted string.
Either give another value or change it so it will use idnumber as well
You can look at query development for formatting here.
e.g.:
insert_stmt = (
"INSERT INTO employees (emp_no, first_name, last_name, hire_date) "
"VALUES (%s, %s, %s, %s)"
)
data = (2, 'Jane', 'Doe', datetime.date(2012, 3, 23))
cursor.execute(insert_stmt, data)
Your code can be rewritten something like this using better formatting:
import sys
nomor = sys.argv[1]
data_str_value = ','.join(['%s'] * len(data))
.....
query = "insert into {idnumber}_recipe values ({values})".format(idnumber = nomor, values = data_str_value)
.....
Note: This code is showing only better formatting as per the example given. This query may or may not run as expected due to incorrect syntax.

How do I extract a nested tuple from a tuple?

I'm using snscrape to scrape instagram. snscrape returns the data in tuple format but it creates the instagram data in a nested tuple. eg.
for b in enumerate(sninstagram.InstagramUserScraper(username='houston_2731').get_items()):
print[(b)]
output
(0, InstagramPost(url='https://www.instagram.com/p/CUdFfjEImHN/', date=datetime.datetime(2021, 9, 30, 17, 39, 20, tzinfo=datetime.timezone.utc), content='"Hardwork plus patience. A symbol of my sacrifice I\'m doing waiting." Nipsey Hussle \n\nIt\'s hard to believe what 5 months and a disciplined diet and hitting the gym hard can do. The first pic in the collage is me at a challenging point in my life. Depression and what not but I had to snap out of it and get in the gym and do the work. As I continue to embark on this fitness journey. I hope to inspire some to join me on this journey. \n\n#fitness #weightloss #muscles #gymmotivation #gymrat #intermittentfasting #fitnessmotivation #fitnessjourney #tenpercentbodyfat #shredded #fitnessgoals #hardwork #patience #discipline #dedication #hunger', thumbnailUrl='https://instagram.fjnb12-1.fna.fbcdn.net/v/t51.2885-15/243385646_584565779558058_6508985384396360110_n.webp?stp=dst-jpg_e35_s640x640_sh0.08&_nc_ht=instagram.fjnb12-1.fna.fbcdn.net&_nc_cat=106&_nc_ohc=nrtaOwxdg64AX8NQE-Z&edm=ABfd0MgBAAAA&ccb=7-4&oh=00_AT_xE-O75IP4MezdzoHM_WxAgbXiivb3aBFUMopAkxxJSA&oe=621D237E&_nc_sid=7bff83', displayUrl='https://instagram.fjnb12-1.fna.fbcdn.net/v/t51.2885-15/243385646_584565779558058_6508985384396360110_n.webp?stp=dst-jpg_e35&_nc_ht=instagram.fjnb12-1.fna.fbcdn.net&_nc_cat=106&_nc_ohc=nrtaOwxdg64AX8NQE-Z&edm=ABfd0MgBAAAA&ccb=7-4&oh=00_AT8JXpM2XKqA_d06LV10Qy_Jt1GYnvpjUEeVZZMRIdwgnQ&oe=621D237E&_nc_sid=7bff83', username='houston_2731', likes=1, comments=0, commentsDisabled=False, isVideo=False))
Now for this reason specifically this output cannot be inserted into the database because it creates a value error caused by the nested tuple because of its type. the database doesn't recognize its type and then fails. so now what I want to do is extract the nested tuple and use it as the main tuple. How do I go about doing that?
class insta():
def instagram(self):
dbname = '******'
user = '******'
password = '******'
host = '******'
port = ****
cur = None
conn = None
try:
conn = psycopg2.connect(
dbname = dbname,
user = user,
password = password,
host = host,
port = port
)
cur = conn.cursor()
cur.execute('DROP TABLE IF EXISTS Machine_instagram')
create_table = '''CREATE TABLE IF NOT EXISTS Machine_instagram (
id serial PRIMARY KEY,
url char,
date timestamp,
content char,
thumbnailUrl char,
displayUrl char,
username char,
likes int,
comments int,
commentsDisabled bool,
isVideo bool)'''
cur.execute(create_table)
for b in enumerate(sninstagram.InstagramUserScraper(username='houston_2731').get_items()):
insert_insta = 'INSERT INTO Machine_instagram (url, date, content,thumbnailUrl, displayUrl, username, likes, comments, commentsDisabled, isVideo) VALUES (%s, %s, %s, %s,%s, %s, %s, %s, %s, %s)'
insert_values = [(b)]
for records in insert_values:
cur.execute(insert_insta, records)
conn.commit()
print('completed')
except Exception as error:
print(error)
finally:
if cur is not None:
cur.close()
if conn is not None:
conn.close()
insta1 = insta()
insta1.instagram()

how to take a date as an input and insert it in a table while doing sql connectivity in python

I have tried doing some sql connectivity and faced a problem recently, i could'nt take isert dates into a table. I have given the code below. what should i add in this?
import mysql.connector as con
db = con.connect(host = "localhost", user = "root", password = "root", database = "vish")
if db.is_connected():
print("success")
a = int(input("roll no. : "))
b = input("name : ")
c = int(input("phone : "))
cursor = db.cursor()
q = ("insert into student values({}, '{}', {})".format(a,b,c))
cursor.execute(q)
db.commit()
how do i take date and insert it into a table
If you have a table t and a column c and you wish to insert a date literal, the format for that literal is 'YYYY-MM-DD', so for example:
INSERT INTO t(c) VALUES('2020-01-11')
But whenever you are getting input from the "outside", you are leaving yourself open to SQL Injection attacks and should be using prepared statements. If you have parsed the input date and built a string literal such as '2020-01-11' from the input, then you are safe. But if you have isolated the year, month and day and you are using a prepared statement anyway because there are other values you have not so rigorously validated, you can also use a '?' parameter for the date thus:
from datetime import date
today = date(2020, 1, 11)
cursor = db.cursor()
cursor.execute("INSERT INTO t(c) VALUES(?)", (today,))
cursor.commit()

sqlite3 python query needed for quiz isn't working

For my school project I decided to make a physics revision tool. The tool lets users log in and saves information about their performance on certain questions. As a result of this I realised I needed to name each table used to store each individual users scores so I thought using .format would be appropriate. It seemed to be working fine until the point where i needed to add code that would add information to the table. From the testing i have done on the code so far, i think the problem is because i am using .format it won't actually create any columns. I don't know how to get around that please help. Appropriate sections of code have been provided:
def quesprep():
intro.destroy()
con= sqlite3.connect("login.db")
c= con.cursor()
c.execute("SELECT accid FROM credentials WHERE accountname = ?", (user,))
global results
results=c.fetchall()
con.commit()
con.close()
con= sqlite3.connect("store.db")
c= con.cursor()
c.execute("""CREATE TABLE IF NOT EXISTS {}(mod integer, ques integer,score integer)""".format(results))
c.execute("INSERT INTO {} Values(mod=2,ques=1, score=0)".format(results))
con.commit()
con.close()
ques()
def mod2q1page():
questionspage.destroy()
con= sqlite3.connect("login.db")
c= con.cursor()
c.execute("SELECT accid FROM credentials WHERE accountname = ?", (user,))
global results
results=c.fetchall()
con.commit()
con= sqlite3.connect("store.db")
c= con.cursor()
c.execute("INSERT OR IGNORE INTO {} VALUES(mod=2, ques=2, score=0)" .format(results))
There seems to be several things wrong here.
Format takes a variable inside the {} ... like {0}, {1} etc
Placeholders are the preferred route to take with formatting sql queries ... like you did in your SELECT
I am not sure what the issue is here but if you are trying to add columns, you need to ALTER the table ... not INSERT. INSERT will add a row item. If you can post the error, perhaps we can help a little more. To start you out though, try placeholders in lieu of format.
Also, fetchall returns a list of tuples ... need to send a tuple in sql, not a list.
for x in results:
c.execute("INSERT INTO ? (col1, col2, col3) VALUES (1, 2, 3);", x)
Edit:
I stand corrected - I ran this code:
data = [('user',)]
cursor.execute("INSERT INTO ? (id, email, password) VALUES (1, test, test);", data)
syntax error because you cannot add placeholder to table name. Read here
I used format with the {0}:
cursor.execute("INSERT INTO {0} (id, email, password) VALUES (1, test, test);".format('user'))
The query was successful. I believe that is your problem here.
found a solution:
intro.destroy()
con= sqlite3.connect("login.db")
c= con.cursor()
c.execute("SELECT accountname FROM credentials WHERE accountname = ?", (user,))
results=c.fetchone()
global tablename
tablename=" ".join(map(str, (results)))
con.commit()
con.close()
global m
m="mod"
global q
q="ques"
global s
s="score"
fieldtype="INTEGER"
con=sqlite3.connect("store.db")
c=con.cursor()
c.execute('CREATE TABLE IF NOT EXISTS {} ({fc} {ft}, {sc} {ft2}, {tc} {ft3})'\
.format(tablename, fc=m, ft=fieldtype, sc=q, ft2=fieldtype, tc=s,
ft3=fieldtype))
con.commit()
con.close()

pymysql error: 'str' object has no attribute 'nextset'

I am running into an issue building a random project for myself. I am trying to record entries into a mysql database that the user types in. I am storing them in a dictionary. The error message is
while self.nextset():
AttributeError: 'str' object has no attribute 'nextset'
I have googled and searched for this issue, but I only find issues kind of like it but not the same error.
My table headers in mysql db match the dictionary keys. I do realize I have issues with selection (2) but my error and what I am troubleshooting now is just when I select option (1).
import mysql
import pymysql
from datetime import date, datetime, timedelta
cursor = pymysql.cursors.Cursor
# Function for adding a new entry
def new_entry(name, date, task, time, notes):
# Build dictionary with new entry information
myDict = {
'Employee': name, # Name of employee
'Date': date, # Date of worked task
'Task': task, # Title of Task
'Time': time, # Time spent on task
'Notes': notes # Notes on the task
}
table = ('timesheet')
placeholders = ', '.join(['%s'] * len(myDict))
columns = ', '.join(myDict.keys())
sql = "INSERT INTO %s ( %s ) VALUES ( %s )" % (table, columns,
placeholders)
pymysql.cursors.Cursor.execute(sql, myDict)
#list all entries for a particular employee
def previous_entries(emp_name):
pymysql.cursors.Cursor.execute(
"SELECT * from user_data WHERE Name = %s", (emp_name,))
#list all entries that match a date or search term
#def search_entries():
# return null
#Print a report of this information to the screen, including the date, title
#of task, time spent, employee, and general notes.
if __name__ == '__main__':
#cnx = mysql.connect(user='root', database='me10_mig')
cnx = pymysql.connect(user='root', password='password',
database='me10_mig')
print("Please enter (1), (2), or (3)")
begin = input("Would you like to (1) enter a new entry or (2) display
all
previous entries or (3) display entries that match a date or search
term? ")
if begin == '1':
name = input("Your Name: ")
date = input("Date of Time Worked: ")
task = input("Title of Task: ")
time = input("Time Spent on Task: ")
notes = input("Notes on Time Worked: ")
new_entry(name, date, task, time, notes)
if begin == '2':
name = input("What is the employee name: ")
previous_entries(name)
#if begin == '3':
The error I get says:
Traceback (most recent call last):
File "C:/Users/a089673/Desktop/Python/TeamTreeHouse/Part 4/timesheet.py", line 61, in <module>
new_entry(name, date, task, time, notes)
File "C:/Users/a089673/Desktop/Python/TeamTreeHouse/Part 4/timesheet.py", line 27, in new_entry
pymysql.cursors.Cursor.execute(sql, myDict)
File "C:\Users\a089673\AppData\Roaming\Python\Python36\site packages\pymysql\cursors.py", line 165, in execute
while self.nextset():
AttributeError: 'str' object has no attribute 'nextset'
Process finished with exit code 1
Any suggestions?
I suspect your might stem from using a dict to hold the arguments to .execute(), but not using named string patterns in the SQL statement.
The docs suggest using %s when passing a list or tuple, but rather use %(name)s when passing a dict.
I suggest you try this code:
def new_entry(name, date, task, time, notes):
# Build dictionary with new entry information
myDict = {
'Employee': name, # Name of employee
'Date': date, # Date of worked task
'Task': task, # Title of Task
'Time': time, # Time spent on task
'Notes': notes # Notes on the task
}
table = ('timesheet')
column_list = []
placeholder_list = []
for k in myDict:
column_list.append(k)
placeholder_list.append('%(' + k + ')s')
sql = "INSERT INTO %s ( %s ) VALUES ( %s )" % (
table,
', '.join(column_list),
', '.join(placeholder_list))
pymysql.cursors.Cursor.execute(sql, myDict)
This will also ensure that the column names and the placeholders are in the same order. Your original code did not consider that (remember, iterating over dicts multimple time is not garanteed to give the same order each time).
I totally overlooked the part where you establish a connection to the database. You need to pass that connection as a parameter to new_entry() and use it.
Try this:
def new_entry(cnx, name, date, task, time, notes):
sql = "INSERT INTO timesheet (Employee, Date, Task, Time, Notes) VALUES (%s, %s, %s, %s, %s)"
values = (name, date, task, time, notes)
with cnx.cursor() as cursor:
cursor.execute(sql, values)
cnx = pymysql.connect(user='root', password='password', database='me10_mig')
new_entry(cnx, ...)

Categories