Coder Social home page Coder Social logo

Comments (5)

zzzeek avatar zzzeek commented on May 27, 2024 1

Hi, I'm traveling this week but sqlalchemy is a pass through to the database here which is deadlocking on two concurrent commands and is extremely normal and typical for postgresql. Alembic migrations should always use a single connection only as well. No bug is illustrated here as yet so let's please continue on the alembic discussion without fanning out multiple bug reports . If some behavior or documentation is not ideal we will open a bug at that point, thanks!

from sqlalchemy.

CaselIT avatar CaselIT commented on May 27, 2024

This seems an asyncpg thing.
This also reproduces:

import asyncio
import asyncpg


url = "postgresql://scott:[email protected]:5432/test"


async def main2():
    connection1 = await asyncpg.connect(url)
    await connection1.execute("drop table if exists table_1 ")
    await connection1.close()

    connection1 = await asyncpg.connect(url)
    await connection1.execute(
        """CREATE TABLE IF NOT EXISTS table_1 (
                id INTEGER NOT NULL, 
                data VARCHAR NOT NULL
            )"""
    )
    await connection1.close()
    connection1 = await asyncpg.connect(url)
    connection2 = await asyncpg.connect(url)
    async with connection1.transaction() as t:
        await connection1.fetch("SELECT 1")
        print("here")
        await connection2.execute(
            "CREATE INDEX CONCURRENTLY ix_1 ON table_1 (data)"
        )


if __name__ == "__main__":
    asyncio.run(main2())

from sqlalchemy.

CaselIT avatar CaselIT commented on May 27, 2024

For reference psycopg3 works correctly

import asyncio
import psycopg

try:
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
except AttributeError:
    pass

url = "postgresql://scott:[email protected]:5432/test"


async def main2():
    async with await psycopg.AsyncConnection.connect(url) as connection1:
        await connection1.execute("drop table if exists table_1 ")
        await connection1.commit()

    async with await psycopg.AsyncConnection.connect(url) as connection1:
        await connection1.execute(
            """CREATE TABLE IF NOT EXISTS table_1 (
                id INTEGER NOT NULL, 
                data VARCHAR NOT NULL
            )"""
        )
        await connection1.commit()
    async with await psycopg.AsyncConnection.connect(
        url
    ) as connection1, await psycopg.AsyncConnection.connect(
        url
    ) as connection2:
        await connection2.set_autocommit(True)
        await (await connection1.execute("SELECT 1")).fetchall()
        print("here")
        await connection2.execute(
            "CREATE INDEX CONCURRENTLY ix_1 ON table_1 (data)"
        )


if __name__ == "__main__":
    asyncio.run(main2())

not really sure what asyncpg is doing here.

from sqlalchemy.

ionsome avatar ionsome commented on May 27, 2024

As I understand prepared statements in asyncpg can leave portals that hold old snapshots. And this makes index creation waiting.

https://www.postgresql.org/docs/current/sql-createindex.html

After the second scan, the index build must wait for any transactions that have a snapshot (see Chapter 13) predating the second scan to terminate.

Not sure if it can be fixed but some portals can be closed manually MagicStack/asyncpg#1088

from sqlalchemy.

CaselIT avatar CaselIT commented on May 27, 2024

It seems very strange that those are causing it since the behaviour happens also after closing the connection.
In the asyncpg example the connection that created the table is closed once that's created, it's not the same connection that hold the transaction, so it should not have any old snapshot held

Psycopg also uses prepared statements i think

from sqlalchemy.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.