Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed #35438 --Failed to insert an model instance into db that utilizes a UUID as its primary key and incorporates a GeneratedField. #18142

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

zshongyi
Copy link

@zshongyi zshongyi commented May 8, 2024

Trac ticket number

ticket-35438

Branch description

I have defined a model that employs a UUIDField as its primary key, accompanied by a JSONField and several GeneratedFields, which are intended for indexing the JSONFields. However, when attempting to load data via loaddata from a JSON fixture, the process fails during the execution of the execute_sql method within django/db/models/SQL/compiler.py. The problematic code snippet is as follows:

def execute_sql(self, returning_fields=None):
    ....
            if not self.returning_fields:
                return []
   ....
            else:
                cols = [opts.pk.get_col(opts.db_table)]
                rows = [
                    (
                        self.connection.ops.last_insert_id(
                            cursor,
                            opts.db_table,
                            opts.pk.column,
                        ),
                    )
                ]
        converters = self.get_converters(cols)
        if converters:
            rows = list(self.apply_converters(rows, converters))
        return rows

Here, returning_fields comprises GeneratedFields, thereby preventing the method from directly returning an empty list at the outset of its logical execution. Moreover, since the model's primary key is not an AUTO_INCREMENT column (it's a UUID), last_insert_id() erroneously returns 0. This subsequently triggers an error within self.apply_converters(rows, converters) as it attempts to treat 0 as a UUID.

To address this issue, the else block logic requires adjustment to accommodate the presence of GeneratedField. Alternatively, within django/db/models/base.py's _save_table method, one could exclude GeneratedField from returning_fields. A modified approach might resemble:

Checklist

  • This PR targets the main branch.
  • The commit message is written in past tense, mentions the ticket number, and ends with a period.
  • I have checked the "Has patch" ticket flag in the Trac system.
  • I have added or updated relevant tests.
  • I have added or updated relevant docs, including release notes if applicable.
  • I have attached screenshots in both light and dark modes for any UI changes.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello! Thank you for your contribution 💪

As it's your first contribution be sure to check out the patch review checklist.

If you're fixing a ticket from Trac make sure to set the "Has patch" flag and include a link to this PR in the ticket!

If you have any design or process questions then you can ask in the Django forum.

Welcome aboard ⛵️!

@sarahboyce
Copy link
Contributor

Hi @zshongyi, this will need a test to be accepted 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants