A transaction is a group of SQL statements that are executed as a single, atomic unit. Either all of them succeed and are committed to the database, or none of them take effect — the database rolls back to its previous state. This guarantee is essential for data integrity: if you insert a new invoice line and then update a stock count in the same transaction, you can be certain you will never end up with one operation persisted and the other lost.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/HotCode2025/Print-Estoy-Cansado-Jefe-TercerSemestre/llms.txt
Use this file to discover all available pages before exploring further.
Manual Transaction Management
By default, psycopg2 opens a transaction automatically the moment you execute the first SQL statement. Changes are not written to disk until you explicitly callconexion.commit(). If something goes wrong, call conexion.rollback() to undo everything since the last commit.
Setting
conexion.autocommit = False makes the default behaviour explicit. psycopg2 already has autocommit off by default, so this line is optional but serves as good documentation:import psycopg2 as bd # Esto es para poder conectarnos a Postgre
conexion = bd.connect(
user='postgres',
password='admin',
host='127.0.0.1',
port='5432',
database='test_bd'
)
try:
conexion.autocommit = False # explicit — already the default
cursor = conexion.cursor()
sentencia = 'INSERT INTO persona(nombre, apellido, email) VALUES (%s, %s, %s)'
valores = ('Maria', 'Esparza', 'mesparza@mail.com')
cursor.execute(sentencia, valores)
print('Termina la transaccion')
except Exception as e:
print(f'Ocurrió un error: {e}')
finally:
conexion.close()
Without an explicit
commit() in the try block, this insert is never persisted — the connection closes and the transaction is rolled back automatically.Add
conexion.commit() in the try block to persist the changes, and conexion.rollback() in the except block to undo them on failure:import psycopg2 as bd # Para poder conectarnos a Postgre
conexion = bd.connect(
user='postgres',
password='admin',
host='127.0.0.1',
port='5432',
database='test_bd'
)
try:
cursor = conexion.cursor()
sentencia = 'INSERT INTO persona(nombre, apellido, email) VALUES (%s, %s, %s)'
valores = ('Maria', 'Esparza', 'mesparza@mail.com')
cursor.execute(sentencia, valores)
conexion.commit() # Persist changes manually
print('Termina la transaccion.')
except Exception as e:
conexion.rollback()
print(f'Ocurrió un error, se hizo un rollback: {e}')
finally:
conexion.close()
Automatic Transactions with the with Statement
Using with conexion: as a context manager removes the need to call commit() and rollback() manually:
- If the
withblock exits normally, psycopg2 automatically callscommit(). - If the
withblock exits via an exception, psycopg2 automatically callsrollback().
transactions_with.py
Common Transaction Exceptions
PostgreSQL has its own user/role system that is independent of the operating system. Always wrap connection code in atry/except to catch and display error messages cleanly.
Common exceptions you may encounter:
| Exception | Typical cause |
|---|---|
psycopg2.OperationalError | Wrong credentials, host unreachable, database does not exist |
psycopg2.errors.InternalError | Transaction aborted; a previous statement failed and was not rolled back |
psycopg2.ProgrammingError | Bad SQL syntax or referencing a non-existent table/column |
Connection Pooling
Opening a new TCP connection to PostgreSQL for every query is expensive. A connection pool keeps a set of open connections alive and lends them out to application code on demand, dramatically reducing latency and resource usage. psycopg2 ships withpsycopg2.pool.SimpleConnectionPool — a thread-safe pool suitable for single-threaded scripts and simple multi-threaded applications.
Creating the Pool
Encapsulate the pool in a class so there is always exactly one pool instance (singleton pattern via the_pool class variable):
connection_pool.py
The pool is configured with
_MIN_CON = 1 and _MAX_CON = 5. psycopg2
opens the minimum number of connections when the pool is first created and
grows up to the maximum as demand increases. Requesting more connections than
_MAX_CON raises a PoolError.Obtaining Connections from the Pool
Callpool.getconn() to borrow a connection and pool.putconn() to return it when done. The obtenerConexion() class method wraps this pattern:
using_the_pool.py
Conexion.obtenerConexion() borrows one slot from the pool. Because _MAX_CON = 5, the example above exhausts the pool on the fifth call. In production code, always return connections promptly:
return_connection.py