Reputation: 2719
I'm trying to save an object to a postgres database using sqlalchemy but am having problems. The below code works, but instead of saving a single instance of location 'Atlanta', and referring to multiple hotels via a foreign key, it is saving the location over and over in the locations table.
How can I set up my code so that I have a single entry 'Atlanta' in the locations table, with multiple hotels referring to that location?
Here are the relevant parts of my code:
class Hotel(Base):
__tablename__ = 'hotels'
id = Column(Integer, primary_key=True)
hotelName = Column(String)
standardRate = Column(Numeric(6, 2))
govtRate = Column(Numeric(6, 2))
standardAvailable = Column(Boolean, nullable=False)
govtAvailable = Column(Boolean, nullable=False)
arrive = Column(Date, nullable=False)
depart = Column(Date, nullable=False)
updated = Column(DateTime, default=datetime.datetime.utcnow, nullable=False)
location_id = Column(Integer, ForeignKey('location.id'))
location = relationship('Location')
class Location(Base):
__tablename__ = 'location'
id = Column(Integer, primary_key=True)
city = Column(String, nullable=False)
def scrape(location, arrive, depart, hotelIDs):
hotels = []
for id in hotelIDs:
hotels.append({
'hotelName': hotelName,
'standardRate': standardRate,
'govtRate': govtRate,
'standardAvailable': standardAvailable,
'govtAvailable': govtAvailable,
'arrive': dateToISO(arrive),
'depart': dateToISO(depart),
'location': Location(city='Atlanta')
})
return hotels
def save_hotel(item):
session = db_setup()
hotel = Hotel(**item)
session.commit()
hotels = scrape("atlanta", "02/20/2016", "02/21/2016", hotelIDs)
for hotel in hotels:
save_hotel(hotel)
Upvotes: 1
Views: 455
Reputation: 11591
It appears that you are creating a new Location
instance on every iteration of your for statement:
for id in hotelIDs:
hotels.append({
'hotelName': hotelName,
'standardRate': standardRate,
'govtRate': govtRate,
'standardAvailable': standardAvailable,
'govtAvailable': govtAvailable,
'arrive': dateToISO(arrive),
'depart': dateToISO(depart),
'location': Location(city='Atlanta') # <- new location instance here
})
Rather, I believe you want to attach all hotels to a single location with something more like this:
location = Location(city='Atlanta')
# or if you already have Atlanta in your database:
# location = session.query(Location).filter_by(city='Atlanta').first()
for id in hotelIDs:
hotel = Hotel( ... )
location.location.append(hotel) # append hotel instance here
...
# now add to session and commit
Upvotes: 1