Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#25430 closed Uncategorized (fixed)

RunSQL documentation is incorrect

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 (5)

comment:1 Changed 5 years ago by Flavio Curella

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

comment:2 Changed 5 years ago by Flavio Curella

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.

comment:4 Changed 5 years ago by Tim Graham <timograham@…>

Resolution: fixed
Status: assignedclosed

In 95edabb4:

Fixed #25430 -- Fixed incorrect RunSQL examples.

comment:5 Changed 5 years ago by Tim Graham <timograham@…>

In 63147dfa:

[1.8.x] Fixed #25430 -- Fixed incorrect RunSQL examples.

Backport of 95edabb45e016ed269f96acc03d4a2bfcecd6b71 from master

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