community.mysql icon indicating copy to clipboard operation
community.mysql copied to clipboard

Can't use "%" in community.mysql.mysql_query

Open MagentoPro opened this issue 3 years ago • 5 comments

I have a query that uses the percentage character in a like statment...

community.mysql.mysql_query: login_db: "{{ db_name }}" login_host: "{{ host }}" login_port: "{{ port }}" login_user: "{{ username }}" login_password: "{{ password }}" query: UPDATE user SET user_name = CONCAT(%(user_name)s,%(ticket)s) WHERE user_name = %(user_name)s AND user_name NOT LIKE '%{{ ticket }}%' named_args: user_name: "{{ item.user_name }}" ticket: "{{ ticket }}"

I get the following error

failed: [127.0.0.1] (item={u'user_name': u'john doe'}) => {"ansible_loop_var": "item", "changed": false, "item": {"user_name": "john doe"}, "msg": "Cannot execute SQL 'UPDATE user SET user_name = CONCAT(%(user_name)s,%(ticket)s) WHERE user_name = %(user_name)s AND user_name NOT LIKE '%SMIG-1111'' args [{'ticket': 'SMIG-1111', 'user_name': 'cemery2174'}]: not enough arguments for format string"}

The query works fine if I run it directly in my database. It seems to be a problem with the % character. It is expecting another parameter because I have % in the LIKE statment.

MagentoPro avatar Oct 29 '21 21:10 MagentoPro

@MagentoPro hi, thanks for reporting this!

@koleo would you like to pick it up?

Andersson007 avatar Nov 01 '21 08:11 Andersson007

Hi,

Yes, I will look to correct this in the next few days.

koleo avatar Nov 01 '21 11:11 koleo

@MagentoPro I have reproduced and identified the issue you reported.

IMHO it's not a bug. As soon as you use named_args or positional_args option, a Python string substitution is applied. So any % character will be a candidate for replacement. If you expect the character % to stay as is, you should double it %%.

So your example should look like:

community.mysql.mysql_query:
    query: >-
        UPDATE user 
        SET user_name = CONCAT(%(user_name)s,%(ticket)s)
        WHERE user_name = %(user_name)s
        AND user_name NOT LIKE '%%{{ ticket }}%%'
    named_args:
        user_name: "{{ item.user_name }}"
        ticket: "{{ ticket }}"

Note that you should Not double the percent sign if you do not use named_args/positional_args:

community.mysql.mysql_query:
    query: >-
        UPDATE user 
        SET user_name = 'test1'
        WHERE user_name = 'test2'
        AND user_name NOT LIKE '%{{ ticket }}%'

koleo avatar Nov 03 '21 22:11 koleo

Thank you. I will give that a try. I appreciate it. Maybe the docs could be updated to state that. No one would ever know to do that otherwise.

MagentoPro avatar Nov 04 '21 05:11 MagentoPro

I won't close the issue because updating the doc sounds sensible. So if anyone wants to do this, welcome. I'll add the doc label.

Andersson007 avatar Nov 08 '21 08:11 Andersson007