0

I'm trying to import data from an excel file into my database in Django. Unfortunately, I'm getting this error when trying to import a time.

    AttributeError at /datavisual/upload/
'datetime.time' object has no attribute 'total_seconds'

Models.py

CallRecord(models.Model):
    timeOfCall = models.DurationField()

and in my Excel logic py file:

class ExcelParser():

 def read_excel(Document):
    wb2 = load_workbook('Sheet1.xlsx',guess_types=True)
    for row in wb2.active.iter_rows(range_string=wb2.active.calculate_dimension()):
        newRecord = CallRecord.objects.create(timeOfCall = row[1].value)
        newRecord.save()

So far, the rest of the fields are saving as expected but I'm not sure what is causing this issue.

Full error report:

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/datavisual/upload/

Django Version: 2.0.1
Python Version: 3.6.4
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'datavisual.apps.DatavisualConfig']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']

Traceback:

File "C:\Users\d_aqu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\exception.py" in inner
  35.             response = get_response(request)

File "C:\Users\d_aqu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  128.                 response = self.process_exception_by_middleware(e, request)

File "C:\Users\d_aqu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  126.                 response = wrapped_callback(request, *callback_args,  **callback_kwargs)

File "C:\Michael\callcentre\callcentre\datavisual\views.py" in model_form_upload
  29.             ExcelParser.read_excel(request.FILES['file'])

File "C:\Michael\callcentre\callcentre\datavisual\ExcelParser.py" in read_excel
  21.               invoiceNumber = row[19].value)

File "C:\Users\d_aqu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\manager.py" in manager_method
  82.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "C:\Users\d_aqu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\query.py" in create
  417.         obj.save(force_insert=True, using=self.db)

File "C:\Users\d_aqu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\base.py" in save
  729.                        force_update=force_update, update_fields=update_fields)

File "C:\Users\d_aqu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\base.py" in save_base
  759.             updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)

File "C:\Users\d_aqu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\base.py" in _save_table
  842.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)

File "C:\Users\d_aqu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\base.py" in _do_insert
  880.                                using=using, raw=raw)

File "C:\Users\d_aqu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\manager.py" in manager_method
  82.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "C:\Users\d_aqu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\query.py" in _insert
  1125.         return query.get_compiler(using=using).execute_sql(return_id)

File "C:\Users\d_aqu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\sql\compiler.py" in execute_sql
  1280.             for sql, params in self.as_sql():

File "C:\Users\d_aqu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\sql\compiler.py" in as_sql
  1233.                 for obj in self.query.objs

File "C:\Users\d_aqu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\sql\compiler.py" in <listcomp>
  1233.                 for obj in self.query.objs

File "C:\Users\d_aqu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\sql\compiler.py" in <listcomp>
  1232.                 [self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]

File "C:\Users\d_aqu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\sql\compiler.py" in prepare_value
  1172.             value = field.get_db_prep_save(value, connection=self.connection)

File "C:\Users\d_aqu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\fields\__init__.py" in get_db_prep_save
  767.         return self.get_db_prep_value(value, connection=connection, prepared=False)

File "C:\Users\d_aqu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\fields\__init__.py" in get_db_prep_value
  1634.         return int(round(value.total_seconds() * 1000000))

Exception Type: AttributeError at /datavisual/upload/
Exception Value: 'datetime.time' object has no attribute 'total_seconds'
Antwane
  • 20,760
  • 7
  • 51
  • 84
M.Throw
  • 145
  • 1
  • 2
  • 11
  • 1
    This traceback is useless, please provide code where you call `total_seconds()` instead. The problem is `'datetime.time' object has no attribute 'total_seconds'`. Which means it is called on the wrong object. – akarilimano Feb 07 '18 at 15:08
  • 1
    The code that is being called in django.db.models.fields is in DurationField, which implies you are using that field rather than TimeField as you claimed. Please post the actual models. – Daniel Roseman Feb 07 '18 at 15:33
  • The exception is fairly self-explanatory: you're passing an object that doesn't have the expected property. Your code is a bit too convoluted to debug this kind of thing easily. A couple more lines would help a lot. – Charlie Clark Feb 07 '18 at 16:17
  • I never call "total_seconds". As far as I can tell, it's done by Django. The error itself is fairly self explanatory, I just don't know enough about Django to understand the problem. You're right about the DurationField, I've edited it to reflect that. – M.Throw Feb 07 '18 at 16:31

1 Answers1

0

The reported error is pretty clear:

AttributeError at /datavisual/upload/
'datetime.time' object has no attribute 'total_seconds'

It's not so easy to tell you exactly what happened since the traceback you gave doesn't correspond to the code you provided. Anyway, at some point, you probably tried to initialize your DurationField with a datetime.time value, whereas it is supposed to be filled with a datetime.timedelta.

You may debug your code and ensure your Excel document parser return datetime.timedelta objects instead of datetime.time.

Look at this line

newRecord = CallRecord.objects.create(timeOfCall = row[1].value)

and check the value returned by row[1].value, or if I trust the traceback, look at line 21 of file ExcelParser.py:

invoiceNumber = row[19].value)

Converting a datetime.time value into timedelta is not a big deal. You only need to know what exactly the time value represents, and compute the corresponding duration (ex: from midnight the same day, from the jan. 1st of the same year, etc.). See this post for more info.

Antwane
  • 20,760
  • 7
  • 51
  • 84