vendredi 14 novembre 2014

base de données - Django « Colonne est pas Unique » avec get_or_create() - Stack Overflow


Using Django 1.6, I am getting 'django.db.utils.IntegrityError: column thread_id is not unique'. Indeed, there exists a object/record #3477. But what I don't understand is that I am using get_or_create()...so if the record is there it shouldn't be trying to add it. Not sure what to do about this and why it is doing this.


def database_udpate(thread_batch):
sanitized_threads = []
query_set = ThreadVault.objects.all()
for thread in thread_batch:
print thread
obj, created = query_set.get_or_create(
thread_id=thread["thread_id"],
author_username=thread["author_username"],
latest_post_date=thread["latest_post_date"],
url=thread["url"],
reply_count=thread["reply_count"],
forum_id=thread["forum_id"],
author_name=thread["author_name"],
subject=thread["subject"],
defaults={ 'assigned_irc_name' :
None })
sanitized_threads.append(obj)
unanswered_threads_table(sanitized_threads)


File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 450, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: column thread_id is not unique

UPDATE/EDIT:


models.py:


class ThreadVault(models.Model):
thread_id = models.BigIntegerField(unique=True)
url = models.CharField(max_length="200")
author_username = models.CharField(max_length="50")
author_name = models.CharField(max_length="50")
forum_id = models.CharField(max_length="50")
subject = models.CharField(max_length="200")
reply_count = models.CharField(max_length=("3"))
latest_post_date = models.CharField(max_length=("50"))
assigned_irc_name = models.ForeignKey(Employee,
null=True, blank=True)

objects = models.Manager()
#unassigned_threads = UnassignedThread()

def __unicode__(self):
return str(self.thread_id)

Traceback:


Traceback (most recent call last):
File "get_unaswered_threads.py", line 92, in <module>
get_unanswered_threads()
File "get_unaswered_threads.py", line 53, in get_unanswered_threads
database_udpate(thread_batch)
File "get_unaswered_threads.py", line 73, in database_udpate
None })
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/models/query.py", line 388, in get_or_create
six.reraise(*exc_info)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/models/query.py", line 380, in get_or_create
obj.save(force_insert=True, using=self.db)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/models/base.py", line 545, in save
force_update=force_update, update_fields=update_fields)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/models/base.py", line 573, in save_base
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/models/base.py", line 654, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/models/base.py", line 687, in _do_insert
using=using, raw=raw)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/models/manager.py", line 232, in _insert
return insert_query(self.model, objs, fields, **kwargs)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/models/query.py", line 1511, in insert_query
return query.get_compiler(using=using).execute_sql(return_id)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 899, in execute_sql
cursor.execute(sql, params)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/backends/util.py", line 69, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/backends/util.py", line 53, in execute
return self.cursor.execute(sql, params)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/utils.py", line 99, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/backends/util.py", line 53, in execute
return self.cursor.execute(sql, params)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 450, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: column thread_id is not unique



Clearly, some of those fields have changed since the last save to the database, otherwise you wouldn't need to update the record. get_or_create will query to match all of the attributes, which is why it isn't really a very useful function. You could move the non-matching ones to defaults, but the problem now is that they won't be updated if the record does exist.


Instead, it's probably better to use get within a try/except and update where necessary:


try:
thread_vault = ThreadVault.objects.get(id=thread['thread_id']
except ThreadVault.DoesNotExist:
thread_vault = ThreadVault()
thread_vault.author_username=thread["author_username"]
# etc.

(It seems that in the upcoming version 1.7 there will be an update_or_create method which does exactly this, see the docs.




The manual has this to say:



The get_or_create() method has similar error behavior to create() when you’re using manually specified primary keys. If an object needs to be created and the key already exists in the database, an IntegrityError will be raised.



I could be off, but at a guess: since thread_id matches, all the other columns should match as well (and match exactly). Since that doesn't happen, an IntegrityError is raised. Perhaps thread_id is a unique column?



Using Django 1.6, I am getting 'django.db.utils.IntegrityError: column thread_id is not unique'. Indeed, there exists a object/record #3477. But what I don't understand is that I am using get_or_create()...so if the record is there it shouldn't be trying to add it. Not sure what to do about this and why it is doing this.


def database_udpate(thread_batch):
sanitized_threads = []
query_set = ThreadVault.objects.all()
for thread in thread_batch:
print thread
obj, created = query_set.get_or_create(
thread_id=thread["thread_id"],
author_username=thread["author_username"],
latest_post_date=thread["latest_post_date"],
url=thread["url"],
reply_count=thread["reply_count"],
forum_id=thread["forum_id"],
author_name=thread["author_name"],
subject=thread["subject"],
defaults={ 'assigned_irc_name' :
None })
sanitized_threads.append(obj)
unanswered_threads_table(sanitized_threads)


File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 450, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: column thread_id is not unique

UPDATE/EDIT:


models.py:


class ThreadVault(models.Model):
thread_id = models.BigIntegerField(unique=True)
url = models.CharField(max_length="200")
author_username = models.CharField(max_length="50")
author_name = models.CharField(max_length="50")
forum_id = models.CharField(max_length="50")
subject = models.CharField(max_length="200")
reply_count = models.CharField(max_length=("3"))
latest_post_date = models.CharField(max_length=("50"))
assigned_irc_name = models.ForeignKey(Employee,
null=True, blank=True)

objects = models.Manager()
#unassigned_threads = UnassignedThread()

def __unicode__(self):
return str(self.thread_id)

Traceback:


Traceback (most recent call last):
File "get_unaswered_threads.py", line 92, in <module>
get_unanswered_threads()
File "get_unaswered_threads.py", line 53, in get_unanswered_threads
database_udpate(thread_batch)
File "get_unaswered_threads.py", line 73, in database_udpate
None })
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/models/query.py", line 388, in get_or_create
six.reraise(*exc_info)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/models/query.py", line 380, in get_or_create
obj.save(force_insert=True, using=self.db)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/models/base.py", line 545, in save
force_update=force_update, update_fields=update_fields)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/models/base.py", line 573, in save_base
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/models/base.py", line 654, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/models/base.py", line 687, in _do_insert
using=using, raw=raw)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/models/manager.py", line 232, in _insert
return insert_query(self.model, objs, fields, **kwargs)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/models/query.py", line 1511, in insert_query
return query.get_compiler(using=using).execute_sql(return_id)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 899, in execute_sql
cursor.execute(sql, params)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/backends/util.py", line 69, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/backends/util.py", line 53, in execute
return self.cursor.execute(sql, params)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/utils.py", line 99, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/backends/util.py", line 53, in execute
return self.cursor.execute(sql, params)
File "/home/one/.virtualenvs/bot/local/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 450, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: column thread_id is not unique


Clearly, some of those fields have changed since the last save to the database, otherwise you wouldn't need to update the record. get_or_create will query to match all of the attributes, which is why it isn't really a very useful function. You could move the non-matching ones to defaults, but the problem now is that they won't be updated if the record does exist.


Instead, it's probably better to use get within a try/except and update where necessary:


try:
thread_vault = ThreadVault.objects.get(id=thread['thread_id']
except ThreadVault.DoesNotExist:
thread_vault = ThreadVault()
thread_vault.author_username=thread["author_username"]
# etc.

(It seems that in the upcoming version 1.7 there will be an update_or_create method which does exactly this, see the docs.



The manual has this to say:



The get_or_create() method has similar error behavior to create() when you’re using manually specified primary keys. If an object needs to be created and the key already exists in the database, an IntegrityError will be raised.



I could be off, but at a guess: since thread_id matches, all the other columns should match as well (and match exactly). Since that doesn't happen, an IntegrityError is raised. Perhaps thread_id is a unique column?


0 commentaires:

Enregistrer un commentaire