Calling DATE_FORMAT() in MySQL from Django fails

隐身守侯 提交于 2019-12-13 01:25:20

问题


I can run SET statements to assign variables and use "transaction" to maintain it in the mySQL session, but when I include the function DATE_FORMAT like this:

cursor.execute("SET @dowToday:=CAST( DATE_FORMAT( NOW(), '%w' ) AS UNSIGNED);")

Django complains that

not enough arguments for format string in /usr/lib/pymodules/python2.6/MySQLdb/cursors.py in execute, line 151

It doesn't help to remove the CAST or to play with or escape the quotes.

Thoughts?


回答1:


I totally missed the point in my previous answer. This is a Django cursor. Not a "standard Python" one.

According to the doc:

https://docs.djangoproject.com/en/dev/topics/db/sql/

Note that if you want to include literal percent signs in the query, you have to double them in the case you are passing parameters:

cursor.execute("SELECT foo FROM bar WHERE baz = '30%%' and id = %s", [self.id])

I assume if this does not work, your could fallback to some simple-and-stupid trick:

cursor.execute("SET @dowToday:=CAST( DATE_FORMAT( NOW(), '%sw' ) AS UNSIGNED);", ['%'])

The %s will be replaced by the % passed as an argument...




回答2:


My guess is that the issue is with the percent sign (%) in the query text. (Isn't that a bind variable placeholder in Django?) e.g. if we were going to use a bind variable, wouldn't that look something like this?

SELECT 'foo' FROM DUAL WHERE 'a' = %(varname)s ;

I think maybe Django is scanning your SQL text and encountering %w and expecting that to be a bind variable. Either that, or it's running an sprintf style function, and encountering the %w and expecting to replace that placeholder with an argument value.

(I haven't tested; so this is just an idea, just a guess.)

As a guess to a workaround, maybe you double up the percent signs, the same we get % literals through an sprintf:

  query("SELECT ... ,'%%w') ...");

If that doesn't work, then maybe it's a backslash character, the same we escape characters in a regular expression:

  query("SELECT ... ,'\%w') ...");

(Or, you might need to double up the backslashes. These are just guesses based on conventions used by other software.)




回答3:


Are you sure the error is produced by that call?


Looking at the code of cursor.py on my system, that leads to:

def execute(self, query, args=None):

    # ...

    if isinstance(query, unicode):
        query = query.encode(charset)
    if args is not None:
        query = query % db.literal(args)         # Line 151

According to that, this exception could only be thrown if args is not None -- which seems impossible considering the call:

cursor.execute("SET @dowToday:=CAST( DATE_FORMAT( NOW(), '%w' ) AS UNSIGNED);")


来源:https://stackoverflow.com/questions/18136629/calling-date-format-in-mysql-from-django-fails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!