mysqlpython-3.xsqlalchemypymysqlsqlmodel

SQLModel: sqlalchemy.exc.ArgumentError: Column expression or FROM clause expected,


I am using the SQLModel library to do a simple select() like described on their official website. However I am getting Column expression or FROM clause expected error message

from typing import Optional

from sqlmodel import Field, Session, SQLModel, create_engine, select

from models import Hero
    
sqrl = f"mysql+pymysql:///roo@asdf:localhost:3306/datab"

engine = create_engine(sqrl, echo=True)


def create_db_and_tables():
    SQLModel.metadata.create_all(engine)


def select_heroes():
    with Session(engine) as session:
        statement = select(Hero)
        results = session.exec(statement)
        for hero in results:
            print(hero)


def main():
    select_heroes()


if __name__ == "__main__":
    main()

this is my models/Hero.py code:

from datetime import datetime, date, time
from typing import Optional
from sqlmodel import Field, SQLModel

class Hero(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str
    secret_name: str
    age: Optional[int] = None
    created: datetime
    lastseen: time
     

when I run app.py I get the sqlalchemy.exc.ArgumentError: Column expression or FROM clause expected, got <module 'models.Hero' from '/Users/dev/test/models/Hero.py'>. message


Solution

  • The error message <Column expression or FROM clause expected, got module 'models.Hero' from '/Users/dev/test/models/Hero.py'> tells us:

    The solution is to replace the object causing the error with something that the select or query function would expect to receive, such as an SQLAlchemy or SQLModel ORM model class.

    The import statement from models import Hero only imports the module Hero. Either


    * It's conventional to use all lowercase for module names; following this convention will help you distinguish between modules and models.

    † This approach is preferable in my opinion: accessing the object via the module namespace eliminates the possibility of name collisions (of course it can be combined with lowercase module names).