Opened 9 years ago

Last modified 9 years ago

#25430 closed Uncategorized

RunSQL documentation is incorrect — at Version 2

Reported by: Flavio Curella Owned by: Flavio Curella
Component: Documentation Version: 1.8
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Flavio Curella)

The current documentation for the RunSQL operation (https://docs.djangoproject.com/en/dev/ref/migration-operations/#runsql) includes the following example:

migrations.RunSQL(["INSERT INTO musician (name) VALUES (%s);", ['Reinhardt']])

That didn't work for me. The code that actually executes the replacement, in django.db.migrations.operations.special.RunSQL._run_sql is:

    def _run_sql(self, schema_editor, sqls):
        if isinstance(sqls, (list, tuple)):
            for sql in sqls:
                params = None
                if isinstance(sql, (list, tuple)):
                    elements = len(sql)
                    if elements == 2:
                        sql, params = sql
                    else:
                        raise ValueError("Expected a 2-tuple but got %d" % elements)
                schema_editor.execute(sql, params=params)

If I'm reading the code correctly, the provided example should instead be:

migrations.RunSQL([["INSERT INTO musician (name) VALUES (%s);", ['Reinhardt']]])

Indeed, I've found this very same usage in the tests (tests/migrations/test_operations.py:test_run_sql_params@L1541):

        param_operation = migrations.RunSQL(
            # forwards
            (
                "INSERT INTO i_love_ponies (id, special_thing) VALUES (1, 'Django');",
                ["INSERT INTO i_love_ponies (id, special_thing) VALUES (2, %s);", ['Ponies']],
                ("INSERT INTO i_love_ponies (id, special_thing) VALUES (%s, %s);", (3, 'Python',)),
            ),
            # backwards
            [
                "DELETE FROM i_love_ponies WHERE special_thing = 'Django';",
                ["DELETE FROM i_love_ponies WHERE special_thing = 'Ponies';", None],
                ("DELETE FROM i_love_ponies WHERE id = %s OR special_thing = %s;", [3, 'Python']),
            ]
        )

Looking throughout the docs, I could not find any usage such as the one referred in the doc. That is value replacement where the sql is a list made of SQL statement + the list params. The only usage I could find are instances of list of list of SQL + params.

Change History (2)

comment:1 by Flavio Curella, 9 years ago

Description: modified (diff)
Owner: changed from nobody to Flavio Curella
Status: newassigned

comment:2 by Flavio Curella, 9 years ago

Description: modified (diff)

I'm filing this as a documentation fix because a) it's eaasier and b) I'm assuming there's people out there that just dealt with it and are using the nested tuple form.

If you think the bug is in the code, and it should behave as documented, let me know and I can work on fixing it.

Note: See TracTickets for help on using tickets.
Back to Top