Syntax error in SQL IF statement - python

I'm using python Flask and can't get my head around why i'm getting error:
ProgrammingError: syntax error at or near "IF"
LINE 1: IF SELECT count(*) FROM ProfilePicture WHERE userid =
Here is my code:
> def updateProfilePicture(filename, image, userid):
> cursor = getCursor()
> binary = psycopg2.Binary(image)
> data = (userid, filename, binary, userid, filename, binary, userid)
> #SQL = """INSERT INTO ProfilePicture(id, image, userid)
> # VALUES (%s, %s, %s)"""
> SQL = """IF SELECT count(*) FROM ProfilePicture WHERE userid = %s > 0
> THEN
> UPDATE ProfilePicture SET id = %s, image = %s WHERE userid = %s
> ELSE
> INSERT INTO ProfilePicture(id, image, userid) VALUES (%s, %s, %s)
> END IF"""
> print cursor.mogrify(SQL, data)
> cursor.execute(SQL, data)
> cursor.connection.commit()
> cursor.close()
> return
A simple insert works well but not the if statement.
Appreciate your help!

Since "ON CONFLICT" syntax is introduced in PostgreSQL 9.5, you have to test the existence of the row in python.
If you have a unique constraint on the userid you can use exceptions:
def updateProfilePicture(filename, image, userid):
cursor = getCursor()
binary = psycopg2.Binary(image)
data = (userid, filename, binary, userid, filename, binary, userid)
SQL = """INSERT INTO ProfilePicture(id, image, userid) VALUES (%s, %s, %s)"""
try:
cursor.execute(SQL, data)
except:
cursor.rollback()
SQL = """UPDATE ProfilePicture SET id = %s, image = %s WHERE userid = %s"""
cursor.execute(SQL, data)
cursor.connection.commit()
cursor.close()

That's not SQL syntax, it's the PL/pgSQL procedural language. It's primarily used to write functions. You can use it for a one-off command, but you need to put it in a DO block:
DO $$
BEGIN
IF (SELECT count(*) FROM ProfilePicture WHERE userid = %s) > 0 THEN
UPDATE ProfilePicture SET id = %s, image = %s WHERE userid = %s;
ELSE
INSERT INTO ProfilePicture(id, image, userid) VALUES (%s, %s, %s);
END IF;
END
$$
Note, however, that your logic will not work if someone else is inserting into/deleting from ProfilePicture at the same time; you risk either losing the update, or inserting multiple records for the same userid. Avoiding this is less than straightforward.

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.

How to store data into database using PyMYSQL in python

I am scraping a website and getting the companies details from it, Now I trying to store the data into database. But I am getting some error like
raise InternalError(errno, errorvalue)
pymysql.err.InternalError: (1054, "Unknown column 'companyaddress' in 'field list'")
Here is my code
for d in companydetail:
lis = d.find_all('li')
companyname = lis[0].get_text().strip()
companyaddress = lis[1].get_text().strip()
companycity = lis[2].get_text().strip()
try:
companypostalcode = lis[3].get_text().strip()
companypostalcode = companypostalcode.replace(",","")
except:
companypostalcode = lis[3].get_text().strip()
try:
companywebsite = lis[4].get_text().strip()
except IndexError:
companywebsite = 'null'
print (companyname)
print (companyaddress)
print (companycity)
print (companypostalcode)
print (companywebsite)
try:
with connection.cursor() as cursor:
print ('saving to db')
cursor.execute("INSERT INTO company(companyname,address,city,pincode,website) VALUES (companyname,companyaddress,companycity,companypostalcode,companywebsite)")
connection.commit()
connection.close()
I am getting my data which I want but it I am not able to store data into database.
The result which I get while print (companyname) and print (campanyaddress) is :
NINGBO BOIGLE DIGITAL TECHNOLOGY CO.,LTD.
TIANYUAN INDUSTRIAL ZONE CIXI NINGBO
ZHEJIANGNINGBO
315325
http://www.boigle.com.cn
You cannot simply use variable names inside a query string as you do:
cursor.execute("INSERT INTO company(companyname,address,city,pincode,website) VALUES (companyname,companyaddress,companycity,companypostalcode,companywebsite)")
Instead, pass your variables into the query making it parameterized:
params = (companyname, companyaddress, companycity, companypostalcode, companywebsite)
cursor.execute("""
INSERT INTO
company
(companyname, address, city, pincode, website)
VALUES
(%s, %s, %s, %s, %s)
""", params)
In
cursor.execute("INSERT INTO company(companyname,address,city,pincode,website) VALUES (companyname,companyaddress,companycity,companypostalcode,companywebsite)")
the values in the second bracket are interpreted as table fields, rather than as python variables. Try
cursor.execute("""INSERT INTO company(
companyname,address,city,pincode,website)
VALUES (%s, %s, %s, %s, %s)""",
(companyname, companyaddress, companycity,
companypostalcode, companywebsite))
instead. You may also want to consult the docs on that.

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()

How can I format strings to query with mysqldb in Python?

How do I do this correctly:
I want to do a query like this:
query = """SELECT * FROM sometable
order by %s %s
limit %s, %s;"""
conn = app_globals.pool.connection()
cur = conn.cursor()
cur.execute(query, (sortname, sortorder, limit1, limit2) )
results = cur.fetchall()
All works fine but the order by %s %s is not putting the strings in correctly. It is putting the two substitutions in with quotes around them.
So it ends up like:
ORDER BY 'somecol' 'DESC'
Which is wrong should be:
ORDER BY somecol DESC
Any help greatly appreciated!
paramstyle
Parameter placeholders can only be used to insert column values. They can not be used for other parts of SQL, such as table names, statements, etc.
%s placeholders inside query string are reserved for parameters. %s in 'order by %s %s' are not parameters. You should make query string in 2 steps:
query = """SELECT * FROM sometable order by %s %s limit %%s, %%s;"""
query = query % ('somecol', 'DESC')
conn = app_globals.pool.connection()
cur = conn.cursor()
cur.execute(query, (limit1, limit2) )
results = cur.fetchall()
DO NOT FORGET to filter first substitution to prevent SQL-injection possibilities
Not all parts of an SQL query can be parametrized. The DESC keyword for example is not
a parameter. Try
query = """SELECT * FROM sometable
order by %s """ + sortorder + """
limit %s, %s"""
cur.execute(query, (sortname, limit1, limit2) )
You could try this alternatively...
query = """SELECT * FROM sometable
order by {0} {1}
limit {2}, {3};"""
sortname = 'somecol'
sortorder = 'DESC'
limit1 = 'limit1'
limit2 = 'limit2'
print(query.format(sortname, sortorder, limit1, limit2))

Categories

Resources