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 trialJonathan Grieve
Treehouse Moderator 91,253 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,253 PointsJonathan Grieve
Treehouse Moderator 91,253 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,457 PointsChris Freeman
Treehouse Moderator 68,457 PointsMegan Amendola nice catch!!
Jonathan Grieve
Treehouse Moderator 91,253 PointsJonathan Grieve
Treehouse Moderator 91,253 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