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)
Related
I have to delete some dates from mysql by python.
I have tables over 2000. so, I need to finish this code... I can't handle this much by clicking my mouse. I really need help.
well, my guess was like this
sql ="delete from finance.%s where date='2000-01-10'"
def Del():
for i in range(0,len(data_s)):
curs.execute(sql,(data_s[i]))
conn.commit()
Howerver, it doesn't work.
I just though
when I just type like this , it works.
>>> query="delete from a000020 where date ='2000-01-25'"
>>> curs.execute(query) //curs=conn.cursor()
But if I add %s to the syntax, it doesn't work..
>>> table='a000050'
>>> query="delete from %s where date ='2000-01-25'"
>>> curs.execute(query,table)
ProgrammingError: (1064, u"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''a000050' where date ='2000-01-25'' at line 1")
it doesn't work too.
>>> curs.execute(query,(table))
ProgrammingError: (1064, u"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''a000050' where date ='2000-01-25'' at line 1")
a bit different... but same.
>>> curs.execute(query,(table,))
I have read many questions from here, but by just adding () or , it doesn't fixed...
Because I'm beginner for the python and mysql, I really need your help. Thank you for reading.
I had the same issue and I fixed by appending as:
def Del():
for i in range(0,len(data_s)):
x = "delete from finance." + data_s[i] + "where date='2000-01-10'"
print x # to check the sql statement :)
curs.execute(x)
conn.commit()
Good question,have a look at MySQLdb User's Guide
paramstyle
String constant stating the type of parameter marker formatting
expected by the interface. Set to 'format' = ANSI C printf format
codes, e.g. '...WHERE name=%s'. If a mapping object is used for
conn.execute(), then the interface actually uses 'pyformat' = Python
extended format codes, e.g. '...WHERE name=%(name)s'. However, the API
does not presently allow the specification of more than one style in
paramstyle.
Note that any literal percent signs in the query string passed to execute() must be escaped, i.e. %%.
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.
Hope this helps.
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'm trying to select a record from my MySQL db, the problem is that it returns with this error which i don't understand, i searched on the web for a solution, and there are many similar cases, but none apply to this specific one.
The expression i'm trying to execute is the following:
result = cursor.execute("""select * from urls where domain = '%s';"""%(found_url,))
it is in a try clause and it always goes right to the except giving me this error:
OperationalError(1054, "Unknown column 'http://..................' in 'field list'")
(i omitted the url, the dots act as placeholders)
after some cycles, being in a loop, it stops giving me that error and changes it to this:
ProgrammingError(2014, "Commands out of sync; you can't run this command now")
any idea? i'm going crazy on this one.
Use query parameters instead of how you are doing it with string interpolation. The protects you against SQL Injection attacks.
cursor.execute("""select * from urls where domain = %s""", (found_url,))
Notice the differences here:
The %s is NOT quoted, as the MySQLdb library will handle this automatically
You are not using string interpolation (no % after the string to replace your placeholders). Instead, you are passing a tuple as the second argument to the execute function.
Since you are only using one place holder and you still need to pass a tuple, there is a comma to indicate it is a tuple (found_url,)
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.
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