Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mac95-0003sk-T2 for psycopg@arkaria.postgresql.org; Wed, 13 Oct 2021 11:10:04 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1mac94-0003aq-SH for psycopg@arkaria.postgresql.org; Wed, 13 Oct 2021 11:10:02 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mac94-0003aV-Ag for psycopg@lists.postgresql.org; Wed, 13 Oct 2021 11:10:02 +0000 Received: from buffalo.birch.relay.mailchannels.net ([23.83.209.24]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mac90-0006Xb-R0 for psycopg@postgresql.org; Wed, 13 Oct 2021 11:10:01 +0000 X-Sender-Id: cp7oy65bvo|x-authuser|paolo@paolodestefani.it Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 4868C541BB4; Wed, 13 Oct 2021 11:09:53 +0000 (UTC) Received: from lu-shared04.cpanelplatform.com (100-96-11-21.trex.outbound.svc.cluster.local [100.96.11.21]) (Authenticated sender: cp7oy65bvo) by relay.mailchannels.net (Postfix) with ESMTPA id 662DE542B51; Wed, 13 Oct 2021 11:09:51 +0000 (UTC) X-Sender-Id: cp7oy65bvo|x-authuser|paolo@paolodestefani.it Received: from lu-shared04.cpanelplatform.com ([UNAVAILABLE]. [107.189.4.2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384) by 100.96.11.21 (trex/6.4.3); Wed, 13 Oct 2021 11:09:53 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: cp7oy65bvo|x-authuser|paolo@paolodestefani.it X-MailChannels-Auth-Id: cp7oy65bvo X-Desert-Unite: 1c16aadb32369679_1634123393015_2784748915 X-MC-Loop-Signature: 1634123393015:4066658995 X-MC-Ingress-Time: 1634123393015 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=paolodestefani.it; s=default; h=Content-Transfer-Encoding:Content-Type: Message-ID:References:In-Reply-To:Subject:Cc:To:From:Date:MIME-Version:Sender :Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=bCncZJhAtRefy1kqOSlLnWv8tReLiu/LydpWGQG8wzU=; b=d0X8yHIz6ZoNOGzIeBgK+4F0QT JyuxGkLlXJX0JX+pBBHcZ6QQ4aAuD37HU4p1xZE9psOhX2Co/j8I7PSJhh3U1KvCKINfP09Kepz4o YebGqf2CzZVMEtlsXpQmHeaQPoKWEHZiCehe91NbUdBxCvQ0RNW1zBvf/MIgvWCvJrQicfF5Wk69u qTvnqJthNfwdyWiX94/uJoN8ZZlwzZy8x+rx4TXgSJUPwQEqIzDJQZB32TheFQYxrqHqiAptTkL+r K9693RiHSSFqcfOdwo/7Iz7OUSHQ0VS+Ql7AuKiqgeva3itSjPG+7/YuZGkstL4zDdxPhU3edS9HD pTayRMWw==; Received: from [::1] (port=59782 helo=lu-shared04.cpanelplatform.com) by lu-shared04.cpanelplatform.com with esmtpa (Exim 4.94.2) (envelope-from ) id 1mac8r-003HaR-8C; Wed, 13 Oct 2021 13:09:49 +0200 MIME-Version: 1.0 Date: Wed, 13 Oct 2021 13:09:49 +0200 From: Paolo De Stefani To: Daniele Varrazzo Cc: Psycopg Subject: Re: psycopg3 transactions In-Reply-To: References: User-Agent: Roundcube Webmail/1.4.11 Message-ID: <9a99d2d110b121542d1ea0a05066858b@paolodestefani.it> X-Sender: paolo@paolodestefani.it Content-Type: text/plain; charset=US-ASCII; format=flowed Content-Transfer-Encoding: 7bit X-AuthUser: paolo@paolodestefani.it List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Well, everything is clear.. BUT I don't understand why a new transaction (committed while in the 'with' context) is not commited (whitout any message) because a previous select statement is not commited. For example: IN PYTHON: PS C:\Users\p.destefani> python Python 3.8.9 (tags/v3.8.9:a743f81, Apr 6 2021, 14:02:34) [MSC v.1928 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import psycopg >>> con = psycopg.connect(host='localhost', port=5433, dbname='test', >>> user='pa_login_role', password='pa_login_password') >>> with con.cursor() as cur: ... cur.execute('select code, description from system.app_user;') ... >>> for i in cur: ... print(i) ... ('system', 'test') ('utente', 'ABCD') >>> IN PSQL: PS C:\Program Files\PostgreSQL\13\bin> .\psql.exe -U postgres -d test -h localhost -p 5433 Inserisci la password per l'utente postgres: psql (13.4) ATTENZIONE: Il code page della console (850) differisce dal code page di Windows (1252). I caratteri a 8-bit potrebbero non funzionare correttamente. Vedi le pagine di riferimento psql "Note per utenti Windows" per i dettagli. Digita "help" per avere un aiuto. test=# select code, description from system.app_user; code | description --------+------------- system | test utente | ABCD (2 righe) IN PYTHON: >>> with con.transaction(): ... with con.cursor() as cur: ... cur.execute("update system.app_user set description = '1234' where code = 'utente';") ... >>> with con.cursor() as cur: ... cur.execute('select code, description from system.app_user;') ... >>> for i in cur: ... print(i) ... ('system', 'test') ('utente', '1234') >>> IN PSQL: test=# select code, description from system.app_user; code | description --------+------------- system | test utente | ABCD (2 righe) So nothing changed for the psql connection even if a transaction was commited (i think...) if i close the connection IN PYTHON: >>> con.close() >>> IN PSQL: test=# select code, description from system.app_user; code | description --------+------------- system | test utente | ABCD (2 righe) i don't see the modified description! if i start a new connection: IN PYTHON: >>> >>> con = psycopg.connect(host='localhost', port=5433, dbname='test', >>> user='pa_login_role', password='pa_login_password') >>> with con.cursor() as cur: ... cur.execute('select code, description from system.app_user;') ... >>> for i in cur: ... print(i) ... ('system', 'test') ('utente', 'ABCD') looks like i didn't modify any description! I tought that the "with con.transaction():" start a new transaction that will be commeted anyway. I have to do a con.commit() BEFORE the with con.transaction() block instead. Or i have to use a transaction for every sql statement that is what i'm doing now. So i don't know if this is the normal/correct behaviour but it's very easy to get wrong and get unexpected results Il 11/10/2021 21:03 Daniele Varrazzo ha scritto: > Hi Paolo, > > in psycopg 3, the normal transaction behaviour demanded by the dbapi > is by default enabled. So, even if you don't use `conn.transaction()`, > a transaction will be started anyway (just, it won't finish at the end > of a block but will need an explicit commit). > > So, > > with con.cursor() as cur: > cur.execute("SELECT * FROM table;") > > does actually start a transaction, and if you don't commit it will not > be terminated. > > If you want to use *only* `conn.transaction()` to manage your > transactions, and leave everything outside a block as autocommit, you > need an autocommit connection, which you can create passing > `autocommit=True` on `connect()` or setting `conn.autocommit = True` > after connection. > > Does it help? > > Cheers > > -- Daniele > > On Mon, 11 Oct 2021 at 20:01, Paolo De Stefani > wrote: >> >> Hi all >> >> In psycopg3 i read and understood the new transaction management >> behaviour. With the use of context managers i have to do something >> like >> this: >> >> con = psycopg.connect() >> with con.transaction(): >> with con.cursor() as cur: >> cur.execute("INSERT INTO table VALUES (1, 2, 3);") >> >> and this works as expected. >> But if i don't need a transaction because i don't need to commit >> anything i can do something like this: >> >> with con.cursor() as cur: >> cur.execute("SELECT * FROM table;") >> >> BUT if a do a select without a transaction the next command that >> require >> a transaction don't works until i do a specific commit >> >> with con.transaction(): >> with con.cursor() as cur: >> cur.execute("DELETE FROM table;") >> >> the delete is effective only for the current connection, i mean other >> db >> user continue to see the without the delete command >> modifications >> Looks like the previous select statement (uncommited) block following >> delete statement even if i use the with con.transaction() statement. >> If a do a con.commit() everything works as expected. >> >> That means i need to use a transaction even for a select statement. >> I can't use autocommit connection in my application. >> >> Is it correct or am i losing anything ??? >> >> >> -- >> Paolo De Stefani >> >> -- Paolo De Stefani