Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bindparam does not work #104

Open
alvassin opened this issue Feb 2, 2020 · 4 comments
Open

bindparam does not work #104

alvassin opened this issue Feb 2, 2020 · 4 comments

Comments

@alvassin
Copy link
Contributor

alvassin commented Feb 2, 2020

Perhaps you could advice some fast fix or workaround for that? I need update for many different rows with different values. Previously used bindparam for that.

import asyncio

from asyncpgsa import PG
from sqlalchemy import Table, MetaData, Column, Integer, String, bindparam, \
    create_engine

metadata = MetaData()

table = Table(
    'citizens',
    metadata,
    Column('test_id', Integer, primary_key=True),
    Column('name', String, nullable=False),
)

DB_URL = 'postgresql://user:[email protected]/db'


async def main():
    # create table
    engine = create_engine(DB_URL)
    metadata.create_all(engine)

    # connect to db
    pg = PG()
    await pg.init(DB_URL)
    async with pg.transaction() as conn:
        # create
        query = table.insert().values([
            {'name': str(i)} for i in range(10)
        ]).returning(table)
        rows = await conn.fetch(query)

        # update
        query = table.update().values(name=bindparam('name'))
        await conn.execute(query, [
            {'test_id': row['test_id'], 'name': row['name'] + '_new'}
            for row in rows
        ])

        # check
        # asyncpg.exceptions.NotNullViolationError: null value in column "name" violates not-null constraint
        # DETAIL:  Failing row contains (31, null).
        results = await conn.execute(table.select())
        print(results)

asyncio.run(main())
@alvassin
Copy link
Contributor Author

alvassin commented Feb 3, 2020

@nhumrich
Copy link
Contributor

nhumrich commented Feb 3, 2020

im not really sure how to fix/handle this one. Sqlalchemy has an "execute many" function in which it strings together a bunch of queries in one transaction for. If it detects execute getting a list, it calls this method instead of the standard excecute. As asyncpg doesnt have that functionality, I am not really sure how to support this.
We could potentially do a similar thing as sqlalchemy and detect whether this is a executemany or not, string together all the requests, seperated by ;, and then execute the entire string. Then replace all the bind's ourselves with the current params.
its enough effort that I dont have time for it currently. But if this is a needed feature for you I would be willing to accept a pull request with tests.

@kchaliki
Copy link

Hello there, am currently stuck on the same issue. Just curious, can this be achieved using the explicit executemany somehow?

@kchaliki
Copy link

Turns out that it does using $1, $2, etc style params and a list of tuples

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants