Python/Django – Expected a string or bytes-like object

Question:

I’ve looked around, and I’ve seen a couple of solutions that I thought would work for my own code, but seemed to do nothing.

I am trying to pull data from a JSON file and add the information to arrays. The arrays will then be used to input data into several objects that I add to the database (I know, this is terribly inefficient, but the way I wrote the original script, I didn’t have to add objects to a database. I am planning on changing that).

Object contains a date time associated with it. I used Python’s strptime function to convert the strings into datetime objects.

In my models.py, I have a DateTimeField for the datetime.

When I try and migrate, however, I get the following error:

TypeError: expected string or bytes-like object

Here is the entire traceback:

Applying interactive_table.0016_auto_20161024_2259...Traceback (most recent call last):
  File "manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "/Users/andrewho/anaconda/lib/python3.5/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
    utility.execute()
  File "/Users/andrewho/anaconda/lib/python3.5/site-packages/django/core/management/__init__.py", line 359, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/andrewho/anaconda/lib/python3.5/site-packages/django/core/management/base.py", line 294, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/andrewho/anaconda/lib/python3.5/site-packages/django/core/management/base.py", line 345, in execute
    output = self.handle(*args, **options)
  File "/Users/andrewho/anaconda/lib/python3.5/site-packages/django/core/management/commands/migrate.py", line 204, in handle
    fake_initial=fake_initial,
  File "/Users/andrewho/anaconda/lib/python3.5/site-packages/django/db/migrations/executor.py", line 115, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "/Users/andrewho/anaconda/lib/python3.5/site-packages/django/db/migrations/executor.py", line 145, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "/Users/andrewho/anaconda/lib/python3.5/site-packages/django/db/migrations/executor.py", line 244, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/Users/andrewho/anaconda/lib/python3.5/site-packages/django/db/migrations/migration.py", line 129, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "/Users/andrewho/anaconda/lib/python3.5/site-packages/django/db/migrations/operations/fields.py", line 84, in database_forwards
    field,
  File "/Users/andrewho/anaconda/lib/python3.5/site-packages/django/db/backends/sqlite3/schema.py", line 231, in add_field
    self._remake_table(model, create_fields=[field])
  File "/Users/andrewho/anaconda/lib/python3.5/site-packages/django/db/backends/sqlite3/schema.py", line 113, in _remake_table
    self.effective_default(field)
  File "/Users/andrewho/anaconda/lib/python3.5/site-packages/django/db/backends/base/schema.py", line 221, in effective_default
    default = field.get_db_prep_save(default, self.connection)
  File "/Users/andrewho/anaconda/lib/python3.5/site-packages/django/db/models/fields/__init__.py", line 755, in get_db_prep_save
    prepared=False)
  File "/Users/andrewho/anaconda/lib/python3.5/site-packages/django/db/models/fields/__init__.py", line 1438, in get_db_prep_value
    value = self.get_prep_value(value)
  File "/Users/andrewho/anaconda/lib/python3.5/site-packages/django/db/models/fields/__init__.py", line 1417, in get_prep_value
    value = super(DateTimeField, self).get_prep_value(value)
  File "/Users/andrewho/anaconda/lib/python3.5/site-packages/django/db/models/fields/__init__.py", line 1275, in get_prep_value
    return self.to_python(value)
  File "/Users/andrewho/anaconda/lib/python3.5/site-packages/django/db/models/fields/__init__.py", line 1378, in to_python
    parsed = parse_datetime(value)
  File "/Users/andrewho/anaconda/lib/python3.5/site-packages/django/utils/dateparse.py", line 93, in parse_datetime
    match = datetime_re.match(value)

For reference, here is my views.py:

def getInfo(counter, hekJSON):
    for counter in range(len(hekJSON["Events"])):
        dateAndTimeHEK.append(convertTimes(hekJSON["Events"][counter]["startTime"]))
        xcen.append(float("%.2f" % hekJSON["Events"][counter]["xCen"]))
        ycen.append(float("%.2f" % hekJSON["Events"][counter]["yCen"]))
        xfov.append(float("%.2f" % hekJSON["Events"][counter]["raster_fovx"]))
        yfov.append(float("%.2f" % hekJSON["Events"][counter]["raster_fovy"]))
        sciObj.append(hekJSON["Events"][counter]["sciObjectives"])


def convertTimes(dateAndTime):
    dateTime = datetime.datetime.strptime(dateAndTime, '%Y-%m-%d %H:%M:%S')
    return dateTime

def display(request):
    noaaNmbr='11809'
    #for right now, this is the only active region that I'm pulling data for. When I get the graph up and running, I will make it more interactive for the user so that he can 

    urlData = "http://www.lmsal.com/hek/hcr?cmd=search-events3&outputformat=json&instrument=IRIS&noaanum="+ noaaNmbr +"&hasData=true"

    webUrl = urlopen(urlData)
    counter = 0
    data = webUrl.read().decode('utf-8')
    hekJSON = json.loads(data)
    getInfo(counter, hekJSON)

    for i in range(getNumberOfEntries(hekJSON)):
        observation = models.HEK_Observations(noaaNmbr=noaaNmbr, dateAndTime=dateAndTimeHEK[i], xcen=xcen[i], ycen=ycen[i], xfov=xfov[i], yfov=yfov[i], sciObj=sciObj[i])
        observation.save()

    return render(request, 'template.html', {'obj': models.HEK_Observations.objects.filter(noaaNmbr=noaaNmbr)})

Here is my models.py:

from django.db import models
import datetime

class HEK_Observations(models.Model):
    dateAndTime = models.DateTimeField(max_length = 40, default = None, verbose_name = 'Date And Time')

Here is my urls.py:

from django.conf.urls import url
from . import views

urlpatterns = [
    # /table/
    url(r'^$', views.display, name='display'),
]

Other solutions to similar problems have said that the problem lies with my default value. However, when I set no defaults (like shown in the code), I still get the same error.

Asked By: Andrew Quoc-Anh Ho

||

Answers:

You’re getting hte error on the migration, so I’m guessing your datetime field was a string, and you’ve made it a date time field. The problem seems to be how your migration is going from those text-elements into dates. Potentially you need to scrub your db either dumping it (if its test data) or making a better manual migration script.

Make Migrations isn’t perfect – if you have existing data thats in different formats you have to make the code to modify the data into new formats and preserve information.

If its just test data (as it usually is), you can just truncate the table – either manually now, (delete the database even), or with a line in the migration script.

Its bad form to ‘delete’ your migration files and make them again (especially if you have multiple users), but if you have good processes around controlling it, it can be done to make clean releases (i.e. one migration per release).

Answered By: Jmons

You should Delete migration files and run migrations again

JUST IN CASE SOMEONE RUNS INTO THIS ERROR OF RECENT.

STEP 1: Go to the migrations folder "migrations".

STEP 2: Navigate to the migration file, the recent one, for example, "0008_auto_20210821_0912.py".

STEP 3: Change the default value that is there from whatever value to "2021-01-05" for DateField or "2021-01-05 06:00:00.000000-09:00" for DateTimeField

I could not agree less with all of the answers provided. The Error raised is perfectly valid. The real issue here is that for your model you have set default=None for the field dateAndTime.

None is not of type DateTime. So when you run your migration, this will raise a TypeError. To fix, delete the migration that was created, remove default = None and instead use blank=True and null=True,
as follows:

class HEKObservations(models.Model):
    date_and_time = models.DateTimeField(max_length=40,
                                         verbose_name='Date And Time',
                                         blank=True,
                                         null=True)

The latter will allow the field to remain empty.

P.S. also note the Python naming convention used.

Answered By: sitWolf
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.