Home > other >  SqlAlchemy update table through foreign key
SqlAlchemy update table through foreign key

Time:04-22

i have 2 tables in my sqlalchemy

book table

class Book(Base):
    __tablename__ = 'books'

    rowid = Column(Integer(), primary_key = True)
    name = Column(String(50), index = True)
    author = Column(String(50))
    year = Column(Integer())
    book_type = Column(Integer(), nullable = False)
    isloaned = Column(Boolean(), nullable = False, default = False)

and loans table

class Loans(db.Base):
    __tablename__ = 'loans'

    loan_id = Column(Integer(), primary_key = True)
    custID = Column(Integer(), ForeignKey(customers.Customer.rowid))
    bookID = Column(Integer(), ForeignKey(books.Book.rowid))
    loan_date = Column(DateTime())
    return_date = Column(DateTime())
    islate = Column(Boolean(), default = True, nullable = False)

    customername = relationship("Customer", foreign_keys = custID)
    bookname = relationship("Book", foreign_keys = bookID)

with the loans table connecting to the book table via foreign key.

now i have a bit of code so when i return a book to the library it updates the loan return date.

with it i want to update the isloaned column inside book, i tried something with this code:

def returnloan(loanid, date):
    with mydb.session as session:
        session.query(Loans).filter(Loans.loan_id == loanid).update({"return_date": date})
        session.query(Loans).filter(Loans.loan_id == loanid).update({"bookname.isloaned": False})
        session.commit()

but i get an error

sqlalchemy.exc.InvalidRequestError: Invalid expression type: 'bookname.isloaned'

the return date is updated but i cant reach the book.isloaned through the foreign key

any suggestions?

CodePudding user response:

You just have to update Book. You'll also ideally need a backref on the Loans table so you can access it from Book:

bookname = relationship("Book", foreign_keys=bookID, backref="loans")

Using the SQLAlchemy 1.4 syntax, you would update something like this:

stmt = update(Loans).where(Loans.loan_id == loan_id).values(return_date=date)
session.execute(stmt)

stmt = update(Book).where(Book.loans.has(Loans.load_id == loan_id)).values(isloaned=False)
session.execute(stmt)

I think with your current syntax, this might work:

session.query(Book).filter(Book.loans.has(Loans.load_id == loan_id)).update({"isloaned": False})

Alternatively, this would be the super easy way just using the ORM:

loan = session.execute(select(Loans).where(Loans.loan_id == loan_id)).scalar()
loan.return_date = date
loan.book.isloaned = False
  • Related