Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
  Jonathan Grieve
Treehouse Moderator 91,254 PointsTypeError: str is not callable
Morning all. :)
Okay, so I'm having a lot of trouble adding a new record to the SQLAlchemy DB.
Admittedly I've made some minor changes to the code, branching out the scope of the project to "Media" rather than just books and added a couple of new fields.
I actually managed it once, adding the data but all the records came up as null.  I think that was because I didn't pass anything in to Media() to the choice 1 code block.   After I did that, I've been hitting a TypeError exception and nothing I've tried has fixed it.
This particular error seems to be a particular case that I'm calling a string as a function that therefore nothing can be done with it.
# import models
from models import (Base, session, Media, engine)
# application imports 
import datetime
import csv
# To display the menu options to the console
def menu():
    while True:
        print('''
            \nMEDIA LIBRARY MENU
            \r1) Add Item
            \r2) View All Books
            \r3) Search Media Item
            \r4) Media Item
            \r5) Exit the Application ''') 
        # store a variable for the menu choice
        choice = input('What would you like to do? ')
        if choice in ['1','2','3','4','5']:
            return choice
        else:
            input('''
                    \rError: Please try again with one of the choices above
                    \rA number from 1 to 5.
                    \rPress Enter to Try Again. ''')
# date field data cleaning and type conversion
def clean_date(date_string):
    months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
    # split and convert date format into usable data
    split_date = date_string.split(" ")
    print(split_date)
    try:
        # convert date digits to integer objects
        month = int(months.index(split_date[0]) + 1)
        day = int(split_date[1].split(',')[0])
        year = int(split_date[2])
        print(day)
        print(month)
        print(year)
        return_date = datetime.date(year, month, day)
    except ValueError:
        input("""
        \n*******eError message. invalid date format:    
        \nUse date format: February 22, 2021
        \n*******
        """)
        return
    else: 
        return return_date
# price field - conversion to integer data type
def clean_price(price_str):
    try:        
        price_float = float(price_str)
    except ValueError:
        input("""Error: price format
        \n\nPrice Format Example: $00.00
        """)
    else:
        # print(price)
        return int(price_float * 100)
# import 
def import_csv():
    with open('media_list.csv') as csvfile:
        data = csv.reader(csvfile)
        # display data in the console
        for row in data:
            print(row)
            media_title = row[0]
            media_type = row[1]
            artist = row[2]
            genre = row[3]
            published_date = clean_date(row[4])
            price = clean_price(row[5])
            new_media = Media(
                media_title=media_title,            
                media_type=media_type, 
                artist=artist, 
                genre=genre, 
                published_date=published_date, 
                price=price
            )
            session.add(new_media)
            session.commit()
# To keep the application running until user exit
def app():
    app_running = True
    while app_running:
        choice = menu()
        if choice == '1':
            # add book/media
            title=input('Media Title:  ')
            type=input('Media Type:  ')
            author=input('Media Author: ')
            genre=input('Genre: ')
            date_error = True
            while date_error:
                date = input('Published Date (Exmp) ')
                date = clean_date(date)
                if type(date) == datetime.date:
                    date_error = False 
            price_error = True
            while price_error:
                price = input('Price (Exmp) ')
                price = clean_price(price)
                if type(price) == int:
                    price_error = False
            # add data to db
            new_media_add = Media(
                media_title=title,            
                media_type=type, 
                artist=author, 
                genre=genre, 
                date=date, 
                price=price
            )
            session.add(new_media_add)
            session.commit()
        elif choice == '2':
            # view book 
            pass
        elif choice == '3':
            # view book 
            pass
        elif choice == '4':
            # analyse - media item details
            pass
        else:             
            # default option to exit the application 
            print('\n\nGOODBYE')
            app_running = False
# Create the Database
if __name__  == '__main__':
    Base.metadata.create_all(engine)
    # call app functions
    # clean_date("June 28, 2021")
    # clean_price("33.33")
    # import_csv()
    app()
    for media in session.query(Media):
        print(media)
## create a database
# Declare the imports
from sqlalchemy import (create_engine, Column, Integer, String, Date)
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
## create a model
# Setup DB for creation
engine = create_engine('sqlite:///media.db', echo=False)
Session = sessionmaker(bind=engine)
session = Session()
Base = declarative_base()
# Setup the database schema  media_ title, author, date published, price
class Media(Base):
    __tablename__ = 'media'
    id= Column(Integer, primary_key=True)
    media_title = Column('Media Title', String)
    media_type = Column('Media Type', String)
    artist = Column('Author/Creator', String)
    genre = Column('Genre', String)
    published_date = Column('Published', Date)
    price = Column('Price', Integer)
    # Display string of data in console - formatted string
    def __repr__(self):
        return f'\n\nMedia Title: {self.media_title} \nMedia Type: {self.media_type} \nArtist: {self.artist} \nGenre: {self.genre} \nPublished Date: {self.published_date} \nPrice: {self.price}' 
1 Answer
Megan Amendola
Treehouse TeacherI think it's because you're missing () with your string columns. Here's an example from the docs for reference. So String() instead of String.
Jonathan Grieve
Treehouse Moderator 91,254 PointsJonathan Grieve
Treehouse Moderator 91,254 PointsThanks for that but I don't think that's quite the issue. I should have specified the stacktrace
It seems to be an issue with the datetime object
Megan Amendola
Treehouse TeacherMegan Amendola
Treehouse TeacherAh ok I think I see what happened. Inside of your app function towards the top, you created a variable called 'type' which is overriding the python type function so it's no longer a function and is instead a string.
Chris Freeman
Treehouse Moderator 68,468 PointsChris Freeman
Treehouse Moderator 68,468 PointsMegan Amendola nice catch!!
Jonathan Grieve
Treehouse Moderator 91,254 PointsJonathan Grieve
Treehouse Moderator 91,254 PointsThanks Megan, that did the trick. 😀
I guess I should have stuck to my guns when I googled the error. What I researched was exactly what was happening. The trouble is it's so much harder to spot when there aren't actually any syntax errors