sqlmodel icon indicating copy to clipboard operation
sqlmodel copied to clipboard

`Unexpected argument(s)` warning in PyCharm when using `select()` with many parameters

Open avi-perl opened this issue 4 years ago • 5 comments

First Check

  • [X] I added a very descriptive title to this issue.
  • [X] I used the GitHub search to find a similar issue and didn't find it.
  • [X] I searched the SQLModel documentation, with the integrated search.
  • [X] I already searched in Google "How to X in SQLModel" and didn't find any information.
  • [X] I already read and followed all the tutorial in the docs and didn't find an answer.
  • [X] I already checked if it is not related to SQLModel but to Pydantic.
  • [X] I already checked if it is not related to SQLModel but to SQLAlchemy.

Commit to Help

  • [X] I commit to help with one of those options 👆

Example Code

from typing import Optional
from datetime import datetime

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


class Item(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    created: datetime
    deleted: bool = False
    category: str
    version: float = 1
    data: str


# Create and save records to show that the query itself is working.
item_1 = Item(created=datetime.now(), category="category_1", data="❤️ I love SQLModel.")
item_2 = Item(created=datetime.now(), category="category_1", data="❤️ I love FastAPI.", deleted=True)
item_3 = Item(created=datetime.now(), category="category_2", data="🥰 I appreciate your work on all of it!")

engine = create_engine("sqlite://")

SQLModel.metadata.create_all(engine)

with Session(engine) as session:
    session.add(item_1)
    session.add(item_2)
    session.add(item_3)
    session.commit()

    # This "statement" is where the issue presents itself in PyCharm
    statement = (
        select(
            Item.category,
            func.count(Item.id),
            func.total(Item.deleted).label("delete_count"),
            func.min(Item.created).label("oldest_timestamp"),
            func.max(Item.created).label("newest_timestamp"),
            func.group_concat(Item.version).label("version_list"),
        )
            .distinct()
            .group_by(Item.category)
    )
    category_metadata = session.exec(statement)
    for result in category_metadata:
        print(dict(result))

Description

  • Using the select() function to write out a query with > 4 params.
  • PyCharm displays the following warning.
Unexpected argument(s) Possible callees: select(entity_0: Type[_TModel_0], entity_1: Type[_TModel_1], entity_2: Type[_TModel_2], entity_3: Type[_TModel_3], **kw) select(entity_0: Type[_TModel_0], entity_1: Type[_TModel_1], entity_2: Type[_TModel_2], entity_3: _TScalar_3, **kw) select(entity_0: Type[_TModel_0], entity_1: Type[_TModel_1], entity_2: _TScalar_2, entity_3: Type[_TModel_3], **kw) select(entity_0: Type[_TModel_0], entity_1: Type[_TModel_1], entity_2: _TScalar_2, entity_3: _TScalar_3, **kw) select(entity_0: Type[_TModel_0], entity_1: _TScalar_1, entity_2: Type[_TModel_2], entity_3: Type[_TModel_3], **kw) select(entity_0: Type[_TModel_0], entity_1: _TScalar_1, entity_2: Type[_TModel_2], entity_3: _TScalar_3, **kw) select(entity_0: Type[_TModel_0], entity_1: _TScalar_1, entity_2: _TScalar_2, entity_3: Type[_TModel_3], **kw) select(entity_0: Type[_TModel_0], entity_1: _TScalar_1, entity_2: _TScalar_2, entity_3: _TScalar_3, **kw) select(entity_0: _TScalar_0, entity_1: Type[_TModel_1], entity_2: Type[_TModel_2], entity_3: Type[_TModel_3], **kw) select(entity_0: _TScalar_0, entity_1: Type[_TModel_1], entity_2: Type[_TModel_2], entity_3: _TScalar_3, **kw) select(entity_0: _TScalar_0, entity_1: Type[_TModel_1], entity_2: _TScalar_2, entity_3: Type[_TModel_3], **kw) select(entity_0: _TScalar_0, entity_1: Type[_TModel_1], entity_2: _TScalar_2, entity_3: _TScalar_3, **kw) select(entity_0: _TScalar_0, entity_1: _TScalar_1, entity_2: Type[_TModel_2], entity_3: Type[_TModel_3], **kw) select(entity_0: _TScalar_0, entity_1: _TScalar_1, entity_2: Type[_TModel_2], entity_3: _TScalar_3, **kw) select(entity_0: _TScalar_0, entity_1: _TScalar_1, entity_2: _TScalar_2, entity_3: Type[_TModel_3], **kw) select(entity_0: _TScalar_0, entity_1: _TScalar_1, entity_2: _TScalar_2, entity_3: _TScalar_3, **kw) select(entity_0: Type[_TModel_0], entity_1: Type[_TModel_1], entity_2: Type[_TModel_2], **kw) select(entity_0: Type[_TModel_0], entity_1: Type[_TModel_1], entity_2: _TScalar_2, **kw) select(entity_0: Type[_TModel_0], entity_1: _TScalar_1, entity_2: Type[_TModel_2], **kw) select(entity_0: Type[_TModel_0], entity_1: _TScalar_1, entity_2: _TScalar_2, **kw) select(entity_0: _TScalar_0, entity_1: Type[_TModel_1], entity_2: Type[_TModel_2], **kw) select(entity_0: _TScalar_0, entity_1: Type[_TModel_1], entity_2: _TScalar_2, **kw) select(entity_0: _TScalar_0, entity_1: _TScalar_1, entity_2: Type[_TModel_2], **kw) select(entity_0: _TScalar_0, entity_1: _TScalar_1, entity_2: _TScalar_2, **kw) select(entity_0: Type[_TModel_0], entity_1: Type[_TModel_1], **kw) select(entity_0: Type[_TModel_0], entity_1: _TScalar_1, **kw) select(entity_0: _TScalar_0, entity_1: Type[_TModel_1], **kw) select(entity_0: _TScalar_0, entity_1: _TScalar_1, **kw) select(entity_0: Type[_TModel_0], **kw) select(entity_0: _TScalar_0, **kw) 
  • This does not impact the use of select(), the query works as expected.
  • This does not show when using <= 4 params.
  • This warning does not show in VSCode.

Operating System

Windows

Operating System Details

Windows = 10 PyCharm Version = 2021.2 (Community Edition)

SQLModel Version

0.0.4

Python Version

Python 3.9.7

Additional Context

image

avi-perl avatar Sep 12 '21 22:09 avi-perl

I have the same issue.

I have a table with 5 foreign keys. And when I want to do a full join like below I get a mypy error. So I assume the typing is the issue here. And PyCharm uses the types too I think.

from sqlmodel import select
...
stmt = (
    select(
        Ticket, TicketStage, ConspicuityType, User, ATFeedbackType, StatisticalEvaluationType
    )
    .join(TicketStage)
    .join(ConspicuityType)
    .join(User)
    .join(ATFeedbackType)
    .join(StatisticalEvaluationType)
)

And when I use reveal_type from typing_extensions I get this:

from typing_extensions import reveal_type
from sqlmodel import select
...
stmt = (
    select(
        Ticket, TicketStage, ConspicuityType, User, ATFeedbackType, StatisticalEvaluationType
    )
    .join(TicketStage)
    .join(ConspicuityType)
    .join(User)
    .join(ATFeedbackType)
    .join(StatisticalEvaluationType)
)
reveal_type(stmt)  # Type of "stmt" is "Any"

When I reduce the arguments to select I get:

from typing_extensions import reveal_type
from sqlmodel import select
...
stmt = (
    select(
        Ticket, TicketStage, ConspicuityType, User
    )
    .join(TicketStage)
    .join(ConspicuityType)
    .join(User)
    .join(ATFeedbackType)
    .join(StatisticalEvaluationType)
)
reveal_type(stmt)  # Type of "stmt" is "Select[Tuple[Ticket, TicketStage, ConspicuityType, User]]"

When I use select from sqlalchemy instead it works with all arguments and I get:

from typing_extensions import reveal_type
from sqlalchemy import select
...
stmt = (
    select(
        Ticket, TicketStage, ConspicuityType, User, ATFeedbackType, StatisticalEvaluationType
    )
    .join(TicketStage)
    .join(ConspicuityType)
    .join(User)
    .join(ATFeedbackType)
    .join(StatisticalEvaluationType)
)
reveal_type(stmt)  # Type of "stmt" is "Select"

Cielquan avatar May 06 '22 08:05 Cielquan

Basically the issues lies here: https://github.com/tiangolo/sqlmodel/blob/main/sqlmodel/sql/expression.py#L140-L442

The overloads are hardcoded and end with 4 parameters. So I guess there are 3 Solutions:

  • Use sqlalchemy's select when using more then 4 parameters for select
  • Add more hardcoded overloads for more parameters, which I guess will grow the amount of overloads exponentially because of the different combinations of _TScalar_X and Type[_TModel_X] for each parameter.
  • Find a dynamic solution if there is any

Cielquan avatar May 06 '22 08:05 Cielquan

Same issue here

kiddten avatar Jun 22 '22 21:06 kiddten