psycopg2 issues with inserting a prepared JSONB object into postgres - python

I have a JSONB object that I want to insert into my database that also contains single quote characters. The example below is just trimmed to highlight my issue:
[{"name": "Moody's Analytics BBB Corp Bd ETF"}]
I have tried just dumping that JSON object to a string and inserting it, but the single ' wont allow that to work and when I try to execute (where detail is the JSON object):
cur.execute("INSERT INTO schmea.table (id, detail) VALUES (?,?)", (sec_id, detail)
I get the following syntax error:
psycopg2.errors.SyntaxError: syntax error at or near ","
LINE 1: INSERT INTO schema.table (id, detail) VALUES (?,?)
^
All of the solutions I've found so far suggest turning the JSON object into a string using json.dumps() but that wont work in my situation because of the single ' character in the name.
Any help is appreciated here.
Edit: Was told that the proper bind is %s not ? but that changes the error to:
psycopg2.ProgrammingError: can't adapt type 'dict'
edit 2:
SOLUTION:
Using the correct %s binds and using json.dumps(detail) fixed the issue.
cur.execute("INSERT INTO schmea.table (id, detail) VALUES (%s,%s)", (sec_id, json.dumps(detail))
Thanks for your help!

The way to pass bind variables to psycopg2 is with %s, not ?.

Related

TypeError: cannot unpack non-iterable int object for face recognition python

I want to do the face recognition for attendance program using python in which the program would detect a face, save the information of the user like ID and Name into people table in MySQL database, and then the program will recognize the face and insert the information of the saved user previously into another table, the attendance table. However, I have encountered an error "TypeError: cannot unpack non-iterable int object" on the coding provided below:
db = database.open()
cursor_person = db.cursor()
cursor_att = db.cursor()
cursor_person.execute("SELECT pID, name_reg FROM people")
for row in cursor_person.fetchone():
pID, name_reg = row
cursor_att.execute("UPDATE attendance(ppID, name_att) SET ('{}', '{}') WHERE" .format (pID, name_reg))
db.commit()
The part where the error occurred is as shown below:
pID, name_reg = row <--- TypeError: cannot unpack non-iterable int object
Does anyone know how to solve this? I hope the information that I have provided is helpful. Thank you in advance.
I believe you would like to use fetchall
Note that your update sql phrase is broken.
for row in cursor_person.fetchall():
cursor_att.execute("UPDATE attendance SET ('{}', '{}') WHERE" .format (row[0], row[1]))
The way to debug this is to print(row) and see what it is.
But I'm guessing your real problem is that those two cursors aren't isolated since they share the same session. The cursor_att.execute() line is probably causing cursor_person.fetchone() to return the number of updated rows, an int 1.
Lastly, you shouldn't use .format to set the UPDATE clause values. Otherwise you're at risk of SQL injection attacks, or just accidental bugs on your own part when values contain characters like '. There's an example on how to properly pass in parameters like so:
cursor.execute("UPDATE attendance SET (%s, %s)", (pID, name_reg))
And the mysql-connector library will automatically escape the strings for you.

Update jsonb field in PostgreSQL with json that contains single quote

I'm using PostgreSQL v9.4.12 and I'm trying to update a jsonb column. I want to update the whole json object and not a specific key of the object.
I'm using a Python dict to store my object and before using it I'm using json.dumps() to transform it to a json formatted String.
However, a value of the json is having a single quote ' that throws an psycopg2.ProgrammingError: syntax error while trying to update.
So far, I've tried:
"UPDATE table "
"SET jsonb_column='{} ".format(json.dumps(new_data)) + ""
"WHERE id='12345'"
Note that new_data is my dict and jsonb_column is the name of the column holding the json data.
The error I'm getting:
psycopg2.ProgrammingError: syntax error at or near "s"
LINE 1: ...code": "BR3", "short_description": "This property's price
is...
^
I was assuming that json.dumps() escapes the single quote but doesn't seem that to be the case. Is there any solution to overcome this error?
Thanks in advance.
json is very fine with single quote, eg:
t=# select $${"short_description": "This property's price is..."}$$::jsonb;
jsonb
------------------------------------------------------
{"short_description": "This property's price is..."}
(1 row)
so I assume you could try using dollar sign quotes, to avoid statement structuring exception with single quotes
The practice of string concatenation is not a good practice.
Better use the way documented in PsyCoPg2 docs.
cur.execute("UPDATE table SET jsonb_column = %s WHERE id = %s", [json, id])

Error in Sqlite while Updating the table using Python

I am using a python to update entries in Sqlite table.
The command I am using is:
handle.execute("UPDATE RECORD set NAME=%s DEVICE=%s PROJECT=%s IP=%s COMMENT=%s where ID = %s"%(arg[2],arg[3],arg[4],arg[5],arg[6],arg[1]))
To this I get am getting an error as:
sqlite3.OperationalError: near "DEVICE": syntax error
I cannot understand what is specifically wrong with Device. Also I have checked the variables are as expected. The data base has a column named device and the database can be opened / accessed and edited using this python file.
There are commas missing between set items.
In addition to that, instead of string formatting, pass parameters to prevent SQL injection:
handle.execute(
"""UPDATE RECORD
SET NAME=%s, DEVICE=%s, PROJECT=%s, IP=%s, COMMENT=%s
WHERE ID = %s""",
(arg[2], arg[3], arg[4], arg[5], arg[6], arg[1]))
UPDATE
If you insist to use string formatting, you should quote %s: '%s'

Insert unicode value into sqlite from python code

I have the following query for inserting values into sqlite3 db, which is made in python code;
insert into 'SplCharTest' ('Id','name','address','telefon') values (1.0, u'cust01', u'addr01 strasse 48908', 2131234213.0)
I am getting the following error when I try to execute this query;
sqlite3CursorObj.execute(dataInsertQueryForSheet)
sqlite3.OperationalError: near "'cust01'": syntax error
I noticed that the presence of u (unicode) in front of 'cust01' is making the problem. Could anybody please tell me how to insert unicode value into sqlite db. Simple usage of 'str' is not possible as I am getting the unicode values from an excel file using openpyxl package and there could be special characters.
Below given is my python code
dataInsertQueryForSheet = "insert into '"+tableNameForSheet+"' ("+columnNamesCSV+") values (%s)" % unicode(rowDataList)[1:(rowDataStrLen-1)]
sqlite3CursorObj.execute(dataInsertQueryForSheet)
Here variable tableNameForSheet contains the table name, columnNamesCSV contains all the columns names in CSV format and rowDataList contains all values to be inserted as an array list.
Any help will be very much appreciated. Thanks in advance.
SQLite always uses Unicode.
The easiest way to use strings while avoiding formatting problems or SQL injection attacks is to use parameters:
sql = "insert into "+tableNameForSheet+" ("+columnNamesCSV+") values (?,?,?,?)"
parameters = [1, u'cust01', u'addr01 strasse 48908', "2131234213"]
cursor.execute(sql, parameters)

Insert a python dict into an SQLite DB

I have a dictionary that I want to add all the values to an sqlite database. All the keys in the dictionary exist in the database, and all the keys are of type string. Yet, I am having trouble with getting the values into the database. The following code is ugly, insecure, and errors whenever it comes across a string with a " in it, but it sort of works.
Query="INSERT INTO packages VALUES("
for tag in Tags:
Query=Query + '"' + Package[tag] + '", '
Query=Query[:-2]+")"
cursor.execute(Query)
How can I elegantly fix this so that it is secure and accepts inputs with " in the string? I've come across a handful of other methods. For example:
fields = Package.keys()
values = Package.values()
query = "INSERT INTO packages (%s) VALUES (%%s);" % (",".join(fields))
cursor.execute(query, values)
but it throws a type error.
TypeError: function takes at most 2 arguments (38 given)
The most elegant solution I have come across so far appears to be
sql_insert = ('INSERT INTO packages (%s) VALUES (%s)' %
(','.join('%s' % name for name in Package),
','.join('%%(%s)s' % name for name in Package)))
cursor.execute(sql_insert, Package)
but it throws an operational error, saying
sqlite3.OperationalError: near "%": syntax error
Once again, my question is how can I elegantly safely add the values from a dictionary to a database?
P.S. It may also be worthy to note that I am using Python 2.5.1.
Afaik, when query has a "?" placeholder execute() method does right escaping automatically basing on argument types. So, the following should work:
query = 'INSERT INTO packages VALUES(%s)' % ','.join(['?'] * len(Tags))
cursor.execute(query, Tags)
I have come across the same problem however i had the problem that not all dictionary entries contained all columns of the table therefore i created the following solution
keys, values = zip(*Package.items())
insert_str = "INSERT INTO packages (%s) values (%s)" % (",".join(keys),",".join(['?']*len(keys)))
cursor.execute(insert_str,values)

Categories