Using Flask, I'm trying to implement HTTP PATCH. I am using SQLite.
Here's what I have:
if 'name' in data.keys():
db.execute('UPDATE places SET name=%s WHERE id=%s', (str(data['name']), str(data_id)))
This yields the following error: OperationalError: near "%": syntax error
What is wrong with my parametrisaton? I've looked up a few examples that pretty much look like this. I tried adding a % before the parameters parenthesis and that is also failing. I also tried concatenating using +'s but that also doesn't work.
In SQLite, parameter placeholders are not %s but ?.
Need a quote like this name='%s' by SQL syntax
Related
I am trying to insert data into a postgres table using variables. Having looked at other answers on this topic it seemed pretty straightforward, however I am getting a syntax error from python before I even get a chance to insert it into the database
The execute statement I am using:
cur.execute("""INSERT INTO "public"."catalogue_product" ("id","structure","upc","title","slug","description","rating","date_created","date_updated","is_discountable","parent_id","product_class_id","collection_id","multiplier","dimension","feat1","feat10","feat2","feat3","feat4","feat5","feat6","feat7","feat8","feat9","image_url","price","short_name","sku") VALUES (nextval'catalogue_product_id_seq'::regclass),'standalone',NULL,%s,'noslug',%s,NULL,current_timestamp,current_timestamp,TRUE,NULL,NULL,NULL,'2.2',%s,'','','','','','','','','','',%s,%s,%s,%s)""", (name, desc, dimension, imageurl, price, shortname, sku))
All parenthesis and quotes match as they should as far as I can see.
What could be causing this?
edit: As per an answer below, I switched to using tripple quotes (and edited the code above to reflect) which does seem to help, but I still get an error:
psycopg2.ProgrammingError: syntax error at or near "'standalone'"
LINE 1: ...ES (nextval'catalogue_product_id_seq'::regclass), 'standalon...
You have an extra ) that closes the VALUES list too early:
... ::regclass),'standalone' ...
THIS^
I'm trying to write an SQL query in PyQt5 that updates some data in a table, but cannot get the query to work. I've read countless forums but as far as I can tell my code is correct. I also have read the documentation back to front so maybe I'm missing something?
I am using PyQt5, python3.5 and SQLITE. The following code (lastError/lastQuery not shown):
self.sqlWrite('ct','MarkerSize',123)
def sqlWrite(self,tbl,var,val):
query = QtSql.QSqlQuery(self.db) # First create query instance.
# Prepare query with placeholders, then bind values.
query.prepare('UPDATE :tbl SET value=:val WHERE property=:var')
query.bindValue(0,tbl)
query.bindValue(1,val)
query.bindValue(2,var)
# Finally execute query.
query.exec_()
...produces the error:
near "?": syntax error Unable to execute statement
near "?": syntax error Unable to execute statement
UPDATE :tbl SET value=:val WHERE property=:var
Parameter count mismatch
Have I lost the plot? What am I missing?
Thanks in advance.
A table name is not a parameter, so you cannot bind a value to it. Placeholders are intended for use with literal values, not arbitrary strings. For the latter, you should just use normal string interpolation:
query.prepare('UPDATE "%s" SET value=:val WHERE property=:var' % tbl)
query.bindValue(':val', val)
query.bindValue(':var', var)
For a more generic way to escape identifiers, use the query's driver:
tbl = query.driver().escapeIdentifier(tbl, QSqlDriver.TableName)
query.prepare('UPDATE %s SET value=:val WHERE property=:var' % tbl)
I'm trying to execute a raw query that is built dynamically.
To assure that the parameters are inserted in the valid position I'm using named parameters.
This seems to work for Sqlite without any problems. (all my tests succeed)
But when I'm running the same code against MariaDB it fails...
A simple example query:
SELECT u.*
FROM users_gigyauser AS u
WHERE u.email like :u_email
GROUP BY u.id
ORDER BY u.last_login DESC
LIMIT 60 OFFSET 0
Parameters are:
{'u_email': '%test%'}
The error I get is a default syntax error as the parameter is not replaced.
I tried using '%' as an indicator, but this resulted in SQL trying to parse
%u[_email]
and that returned a type error.
I'm executing the query like this:
raw_queryset = GigyaUser.objects.raw(
self.sql_fetch, self._query_object['params']
)
Or when counting:
cursor.execute(self.sql_count, self._query_object['params'])
Both give the same error on MariaDB but work on Sqlite (using the ':' indicator)
Now, what am I missing?
edit:
The format needs to have s suffix as following:
%(u_email)s
If you are using SQLite3, for some reason syntax %(name)s will not work.
You have to use :name syntax instead if you want to pass your params as {"name":"value"} dictionary.
It's contrary to the documentation, that states the first syntax should work with all DB engines.
Heres the source of the issue:
https://code.djangoproject.com/ticket/10070#comment:18
I used MySQL Connector/Python API, NOT MySQLdb.
I need to dynamically insert values into a sparse table so I wrote the Python code like this:
cur.executemany("UPDATE myTABLE SET %s=%s WHERE id=%s" % data)
where
data=[('Depth', '17.5cm', Decimal('3003')), ('Input_Voltage', '110 V AC', Decimal('3004'))]
But it resulted an error:
TypeError: not enough arguments for format string
Is there any solution for this problem? Is it possible to use executemany when there is a
substitution of a field in query?
Thanks.
Let's start with the original method:
As the error message suggests you have a problem with your SQL syntax (not Python). If you insert your values you are effectively trying to execute
UPDATE myTABLE SET 'Depth'='17.5cm' WHERE id='3003'
You should notice that you are trying to assign a value to a string 'Depth', not a database field. The reason for this is that the %s substitution of the mysql module is only possible for values, not for tables/fields or other object identifiers.
In the second try you are not using the substitution anymore. Instead you use generic python string interpolation, which however looks similar. This does not work for you because you have a , and a pair of brackets too much in your code. It should read:
cur.execute("UPDATE myTABLE SET %s=%s WHERE id=%s" % data)
I also replaced executemany with execute because this method will work only for a single row. However your example only has one row, so there is no need to use executemany anyway.
The second method has some drawbacks however. The substitution is not guaranteed to be quoted or formatted in a correct manner for the SQL query, which might cause unexpected behaviour for certain inputs and may be a security concern.
I would rather ask, why it is necessary to provide the field name dynamically in the first place. This should not be necessary and might cause some trouble.
Usually i use Django orm for making database related query in python but now i am using the python itself
I am trying to update a row of my mysql database
query ='UPDATE callerdetail SET upload="{0}" WHERE agent="{1}" AND custid="{2}"AND screenname="{3}" AND status="1"'.format(get.uploaded,get.agent,get.custid,get.screenname)
But i am getting the error
query ='UPDATE callerdetail SET upload="{0}" WHERE agent="{1}" AND custid="{2}"AND screenname="{3}" AND status="1"'.format(get.uploaded,get.agent,get.custid,get.screenname)
AttributeError: 'C' object has no attribute 'uploaded'
Please help me what is wrong with my query ?
Get is probably mapping to a c object. Try renaming your "get" object to something else.
Here is a list of reserved words. I don't see get in there, but it sound like it could be part of a c library that's being included. If you're including something with from x import *, you could be importing it without knowing.
In short - get probably isn't what you think it is.
However, before you go much further building SQL queries with string formatting, I strongly advise you not to! Search for "SQL injection" and you'll see why. Python DB API compliant libraries utilise "placeholders" which the library can use to insert the variables into a query for you providing any necessary escaping/quoting.
So instead of:
query ='UPDATE callerdetail SET upload="{0}" WHERE agent="{1}" AND custid="{2}"AND screenname="{3}" AND status="1"'.format(get.uploaded,get.agent,get.custid,get.screenname)
An example using SQLite3 (using ? as a placeholder - others use %s or :1 or %(name)s - or any/all of the above - but that'll be detailed in the docs of your library):
query = "update callerdetail set upload=? where agent=? and custid=? and screename=? and status=?"
Then when it comes to execute the query, you provide the values to be substituted as a separate argument:
cursor.execute(query, (get.uploaded, get.agent, get.custid, get.screenname))
If you really wanted, you could have a convenience function, and reduce this to:
from operator import attrgetter
get_fields = attrgetter('uploaded', 'agent', 'custid', 'screenname')
cursor.execute(query, get_fields(get))