databases icon indicating copy to clipboard operation
databases copied to clipboard

Expanding bindparam in SQLAlchemy query is not properly preprocessed

Open tuffnatty opened this issue 4 years ago • 0 comments

SQLAlchemy queries containing bindparam(expanding=True) need additional preprocessing at execution time.

Relevant documentation: method sqlalchemy.sql.operators.ColumnOperators.in_, attribute sqlalchemy.sql.compiler.SQLCompiler.contains_expanding_parameters.

Self-contained sample:

import asyncio

from databases import Database
import sqlalchemy


DB_URI = 'sqlite:///example.db')

database = Database(DB_URI)
engine = sqlalchemy.create_engine(DB_URI)

metadata = sqlalchemy.MetaData()
notes = sqlalchemy.Table(
    "notes",
    metadata,
    sqlalchemy.Column("id", sqlalchemy.Integer, primary_key=True),
)
metadata.create_all(engine)


async def test():
    await database.connect()

    choices = sqlalchemy.sql.bindparam('choices', expanding=True)
    query = notes.select().where(notes.c.id.in_(choices))

    query = query.params(choices=[42, 43])

    # This runs OK:
    with engine.connect() as connection:
        connection.execute(query)  # OK

    # This fails with:
    # sqlite3.OperationalError: no such column: EXPANDING_choices
    await database.execute(query=query)


if __name__ == '__main__':
    asyncio.run(test())

tuffnatty avatar Jun 16 '20 12:06 tuffnatty