sqlalchemy-stubs icon indicating copy to clipboard operation
sqlalchemy-stubs copied to clipboard

Execution contexts missing some functions

Open bochecha opened this issue 5 years ago • 2 comments

SQLAlchemy allows defining column defaults with a callable getting the insert/update context as an argument (doc), e.g:

def get_default(context):
    return context.get_current_parameters()['name'] + 'whatever'


class MyModel(Base):
    __tablename__ = 'my_model'

    id = Column(Integer, primary_key=True)
    name = Column(Unicode, nullable=False)
    something = Column(Unicode, default=get_default, nullable=False)

I'm trying to add type annotations to the get_default function in my code. For the example above, the return type would be a str (the column is defined as Unicode).

The context argument is (in my case, using PostgreSQL with the pyscopg2 backend) an instance of the sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 class. Its MRO is:

>>> sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2.__mro__
(<class 'sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2'>,
 <class 'sqlalchemy.dialects.postgresql.base.PGExecutionContext'>,
 <class 'sqlalchemy.engine.default.DefaultExecutionContext'>,
 <class 'sqlalchemy.engine.interfaces.ExecutionContext'>,
 <class 'object'>)

The problem is none of these classes have the get_current_parameters() method defined in sqlalchemy-stubs.

In SQLAlchemy, it's defined in sqlalchemy.engine.default.DefaultExecutionContext, all the child classes just inherit from it.

I'd be happy to send a pull request adding the stubs for this function, but I'm unsure about the return value, since it returns a dictionary:

which includes entries for each column/value pair that is part of the INSERT or UPDATE statement. The keys of the dictionary will be the key value of each :class:.Column, which is usually synonymous with the name.

So it seems to me the return value would be a Dict[str, Any], since the key (name) of the Column will be a string, and its type can be anything, depending on how the column is defined.

def get_current_parameters(isolate_multiinsert_groups: bool = True) -> Dict[str, Any]: ...

Is that correct?

bochecha avatar Jan 22 '20 11:01 bochecha

Is that correct?

This looks reasonable to me. PRs are welcome (please don't forget to sign the CLA, see bottom of README).

ilevkivskyi avatar Jan 22 '20 11:01 ilevkivskyi

This looks reasonable to me. PRs are welcome (please don't forget to sign the CLA, see bottom of README).

That's a lot of text to read, and pass on to my employer (or is it my customer? should I get a lawyer?) to sign, for what is effectively a trivial contribution adding a single line.

I think I'll let someone else take over it, and go through the CLA signing only when I have a more significant contribution which makes it worth it.

bochecha avatar Jan 22 '20 16:01 bochecha