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

get() returned more than one Tag -- it returned 2! #826

Open
naskio opened this issue Oct 21, 2022 · 7 comments
Open

get() returned more than one Tag -- it returned 2! #826

naskio opened this issue Oct 21, 2022 · 7 comments

Comments

@naskio
Copy link

naskio commented Oct 21, 2022

Hello
Sometimes when adding tags to an existing object, I am getting the following error.

get() returned more than one Tag -- it returned 2!

Here is the code I am using

...
publication.tags.set(all_tags, clear=True)
publication.save()
# I also tried
publication.tags.set(all_tags)
publication.save()
# and
publication.tags.add(*all_tags)
publication.save()
# but still getting the same issue
...

Notes:

  • I am not using any get function
  • Django version 4.1
@rtpg
Copy link
Contributor

rtpg commented Nov 14, 2022

@naskio do you have a longer stack trace? please post more details.

@naskio
Copy link
Author

naskio commented Nov 26, 2022

2022-11-16 01:06:22.022 | ERROR    | apps.data_collection.management.commands.tagging:handle:69 - get() returned more than one Tag -- it returned 2!
Traceback (most recent call last):

> File "/app/apps/data_collection/management/commands/tagging.py", line 63, in handle
    publication.tags.set(all_tags, clear=True)
    │           │        └ ['libération', 'Direction', 'Algérie Presse Service', 'guerre de libération', 'EN', 'Communauté nationale', 'Vidéo', 'Abdelma...
    │           └ <taggit.managers.TaggableManager: tags>
    └ <Publication: La communauté algérienne en Libye commémore le 68e anniversaire du déclenchement de la Glorieuse guerre de libé...

  File "/usr/local/lib/python3.9/site-packages/taggit/utils.py", line 124, in inner
    return func(self, *args, **kwargs)
           │    │      │       └ {'clear': True}
           │    │      └ (['libération', 'Direction', 'Algérie Presse Service', 'guerre de libération', 'EN', 'Communauté nationale', 'Vidéo', 'Abdelm...
           │    └ <taggit.managers._TaggableManager object at 0x7ff903015be0>
           └ <function _TaggableManager.set at 0x7ff90e52dee0>
  File "/usr/local/lib/python3.9/site-packages/taggit/managers.py", line 273, in set
    self.add(*tags, **kwargs)
    │    │    │       └ {}
    │    │    └ ['libération', 'Direction', 'Algérie Presse Service', 'guerre de libération', 'EN', 'Communauté nationale', 'Vidéo', 'Abdelma...
    │    └ <function _TaggableManager.add at 0x7ff90e52db80>
    └ <taggit.managers._TaggableManager object at 0x7ff903015be0>
  File "/usr/local/lib/python3.9/site-packages/taggit/utils.py", line 124, in inner
    return func(self, *args, **kwargs)
           │    │      │       └ {}
           │    │      └ ('libération', 'Direction', 'Algérie Presse Service', 'guerre de libération', 'EN', 'Communauté nationale', 'Vidéo', 'Abdelma...
           │    └ <taggit.managers._TaggableManager object at 0x7ff903015be0>
           └ <function _TaggableManager.add at 0x7ff90e52daf0>
  File "/usr/local/lib/python3.9/site-packages/taggit/managers.py", line 152, in add
    tag_objs = self._to_tag_model_instances(tags, tag_kwargs)
               │    │                       │     └ {}
               │    │                       └ ('libération', 'Direction', 'Algérie Presse Service', 'guerre de libération', 'EN', 'Communauté nationale', 'Vidéo', 'Abdelma...
               │    └ <function _TaggableManager._to_tag_model_instances at 0x7ff90e52dc10>
               └ <taggit.managers._TaggableManager object at 0x7ff903015be0>
  File "/usr/local/lib/python3.9/site-packages/taggit/managers.py", line 223, in _to_tag_model_instances
    tag = manager.get(name__iexact=name)
          │       │                └ 'UN'
          │       └ <function QuerySet.get at 0x7ff910d86f70>
          └ <QuerySet [<Tag: South Korea>, <Tag: India>, <Tag: Canadian>, <Tag: Australia>, <Tag: Barça>, <Tag: Xavi>, <Tag: Ukraine>, <T...
  File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 499, in get
    raise self.model.MultipleObjectsReturned(
          │    │     └ <class 'taggit.models.Tag.MultipleObjectsReturned'>
          │    └ <class 'taggit.models.Tag'>
          └ <QuerySet [<Tag: South Korea>, <Tag: India>, <Tag: Canadian>, <Tag: Australia>, <Tag: Barça>, <Tag: Xavi>, <Tag: Ukraine>, <T...

taggit.models.Tag.MultipleObjectsReturned: get() returned more than one Tag -- it returned 2!

NOTE:
At the begging I inserted many tags without having TAGGIT_CASE_INSENSITIVE = True but I added it later.
so I guess that I may have inserted some tags (for example UKRAINE and Ukraine) which were not the same but became equal after enabling case insensitivity (having duplicates in the DB).
@rtpg

@rtpg
Copy link
Contributor

rtpg commented Nov 26, 2022

@naskio thank you very much for that detail! It sounds very important.

If in your system you have that problem, the easiest thing to do would be to normalize manually in a database migration. So for example you find all of the TaggedItems that are pointing to UKRAINE and then point them to Ukraine. From there, you should be able to delete UKRAINE.

You'll need to do some database cleanup. I think though that this error should have its own handling, though. And it might even make sense for us to write a helper management command... but at the very least we should document what to do.

@rtpg
Copy link
Contributor

rtpg commented Nov 26, 2022

Good first issue: catching MultipleObjectsReturned and rethrowing it with a better error message to handle this.

@naskio
Copy link
Author

naskio commented Nov 26, 2022

@rtpg
For me the ideal solution would be to have both options:
1- Handling this case by taking only the first tag when get() returns more than one, This would be more flexible enabling us to disable TAGGIT_CASE_INSENSITIVE again without impacting the data.
2- A management command if someone decides to enable TAGGIT_CASE_INSENSITIVE and keep only one instance of similar tags.

@ghost
Copy link

ghost commented Mar 21, 2023

Hi @naskio, can I give a shot at solving this issue?

@naskio
Copy link
Author

naskio commented Mar 21, 2023

Hi @naskio, can I give a shot at solving this issue?

Yes sure
Good luck 😀

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

No branches or pull requests

2 participants