2

I'm trying to have a webpage show all of the upcoming shows listed in a database, along with a bunch of info about each show that's stored in venue and artist tables respectively. I query the Show table, and then for each row in that result I link the Artist and Venue tables. Because the error has something to do with datetime, I'm assuming the error is something to do with either if show.start_time > current_time: or "start_time": show.start_time but the error doesn't pin down where it is. I tried converting both current_time and show.start_time to a string just to see if that worked, but no luck. What am I doing wrong?

@app.route('/shows')
def shows():

  current_time = datetime.now()

  data = []

  allshows = Show.query.all()

  for show in allshows:
    artist = Artist.query.get(show.artist_id)
    venue = Venue.query.get(show.venue_id)

    if show.start_time > current_time:
      data.append({
        "venue_id": show.venue_id,
        "venue_name": venue.name,
        "artist_id": show.artist_id,
        "artist_name": artist.name,
        "artist_image_link": artist.image_link,
        "start_time": show.start_time
      })
 
  return render_template('pages/shows.html', shows=data)

If it helps, here are the models associated with it:

class Venue(db.Model):
    __tablename__ = 'venues'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    city = db.Column(db.String(120))
    state = db.Column(db.String(120))
    address = db.Column(db.String(120))
    phone = db.Column(db.String(120))
    image_link = db.Column(db.String(500))
    facebook_link = db.Column(db.String(120))
    genres = db.Column(db.ARRAY(db.String))
    image_link = db.Column(db.String(500))
    facebook_link = db.Column(db.String(120))
    website = db.Column(db.String(300))
    seeking_talent = db.Column(db.Boolean)
    seeking_description = db.Column(db.String(120))
    shows = db.relationship('Show', backref='venue', lazy=True)

class Artist(db.Model):
    __tablename__ = 'artists'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    city = db.Column(db.String(120))
    state = db.Column(db.String(120))
    phone = db.Column(db.String(120))
    genres = db.Column(db.String(120))
    image_link = db.Column(db.String(500))
    facebook_link = db.Column(db.String(120))
    website = db.Column(db.String(300))
    seeking_shows = db.Column(db.Boolean)
    seeking_description = db.Column(db.String(120))
    shows = db.relationship('Show', backref='artist', lazy=True)        

class Show(db.Model):
    __tablename__ = 'shows'

    id = db.Column(db.Integer, primary_key=True)
    artist_id = db.Column(db.Integer, db.ForeignKey('artists.id'), nullable = False)
    venue_id = db.Column(db.Integer, db.ForeignKey('venues.id'), nullable = False)
    start_time = db.Column(db.DateTime, nullable = False)

    def __repr__(self):
        return '<Show {} {}>'.format(self.artist_id, self.venue_id)

Edit: Including full traceback.

Traceback (most recent call last):
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/app.py", line 2464, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/app.py", line 2450, in wsgi_app
    response = self.handle_exception(e)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/app.py", line 1867, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/app.py", line 547, in shows
    return render_template('pages/shows.html', shows=data)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/templating.py", line 137, in render_template
    return _render(
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/templating.py", line 120, in _render
    rv = template.render(context)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/jinja2/environment.py", line 1090, in render
    self.environment.handle_exception()
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/jinja2/environment.py", line 832, in handle_exception
    reraise(*rewrite_traceback_stack(source=source))
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/jinja2/_compat.py", line 28, in reraise
    raise value.with_traceback(tb)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/templates/pages/shows.html", line 1, in top-level template code
    {% extends 'layouts/main.html' %}
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/templates/layouts/main.html", line 103, in top-level template code
    {% block content %}{% endblock %}
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/templates/pages/shows.html", line 9, in block "content"
    <h4>{{ show.start_time|datetime('full') }}</h4>
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/app.py", line 101, in format_datetime
    date = dateutil.parser.parse(value)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/dateutil/parser.py", line 1168, in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/dateutil/parser.py", line 556, in parse
    res, skipped_tokens = self._parse(timestr, **kwargs)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/dateutil/parser.py", line 675, in _parse
    l = _timelex.split(timestr)         # Splits the timestr into tokens
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/dateutil/parser.py", line 192, in split
    return list(cls(s))
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/dateutil/parser.py", line 60, in __init__
    raise TypeError('Parser must be a string or character stream, not '
TypeError: Parser must be a string or character stream, not datetime

Edit 2: def that formats datetime:

def format_datetime(value, format='medium'):
  date = dateutil.parser.parse(value)
  if format == 'full':
      format="EEEE MMMM, d, y 'at' h:mma"
  elif format == 'medium':
      format="EE MM, dd, y h:mma"
  return babel.dates.format_datetime(date, format)

app.jinja_env.filters['datetime'] = format_datetime
8
  • Please include the entire traceback. As an aside, those many-to-one relationships are good candidates for (joined) eager loading, so you would not have to fetch the artists and venues one by one. I think I remember you attempting to do just that, did it not work out? Commented Aug 5, 2020 at 16:50
  • @IljaEverilä Traceback added. I honestly don't recall, this has been the most frustrating project I've done since starting to learn programming, and with everything else going on in life/the world my head hasn't been completely clear. I'm sure there's more efficient way to do this, but at this point I just need to get this done, I'm already behind schedule for the course I'm in and still have a few things left to do in this before it's done. Commented Aug 5, 2020 at 17:04
  • The error stems from your shows.html template, where it has <h4>{{ show.start_time|datetime('full') }}</h4>. show.start_time is a datetime, which apparently the datetime('full') filter or so does not like, because it seems to be trying to parse the value as if it were a string. Commented Aug 5, 2020 at 17:22
  • So what would be the fix for this? Is there one without changing the HTML? Commented Aug 5, 2020 at 17:24
  • Have you defined the datetime() filter yourself, or is it provided by the template library or the framework? A somewhat ugly solution would be to format show.start_time as a string before passing to the template, but that's band-aid, and you would have to know what format the parser is happy with (ISO 8601 is a good guess). Commented Aug 5, 2020 at 17:27

1 Answer 1

14

From the traceback it can be seen that the exception is raised during rendering of the template. The date formatting filter in

<h4>{{ show.start_time|datetime('full') }}</h4>

seems to expect string values only, and attempts to parse them to a datetime. On the other hand your models use a proper timestamp type, so the attribute show.start_time is already a datetime instance. One way to fix this mismatch is to alter the formatting filter to accept datetime values as well:

def format_datetime(value, format='medium'):
    # instead of just date = dateutil.parser.parse(value)
    if isinstance(value, str):
        date = dateutil.parser.parse(value)
    else:
        date = value
    ...
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.