The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Con Python y SQLite puedes crear un CRM local de aprendizaje para guardar, consultar, modificar y eliminar contactos, sin instalar ni iniciar un proceso de base de datos separado. Esta guía construye ese ciclo CRUD con el módulo estándar sqlite3, una tabla y consultas parametrizadas. El ejemplo asume Python 3.12 o posterior para usar el control explícito de transacciones con autocommit.
Qué crearás y qué necesitas
El resultado será una pequeña aplicación de consola y un archivo crm.db en el directorio del proyecto. La base local conservará los datos entre ejecuciones cuando confirmes los cambios con commit(). SQLite es una biblioteca basada en disco: para este proyecto no hace falta configurar un servidor separado. La documentación de Python describe el módulo y sus operaciones en sqlite3 — DB-API 2.0 interface for SQLite databases.
- Python 3.12 o posterior, elegido aquí porque el ejemplo configura las transacciones con
Connection.autocommit. - Un editor de texto y una terminal.
- Un directorio vacío para el proyecto. No necesitas instalar una dependencia adicional para
sqlite3.
Este es un CRM didáctico, no una aplicación multiusuario ni un sistema con inicio de sesión, permisos, copias de seguridad automáticas o interfaz web.
1. Crear el proyecto y la tabla de contactos
Crea un directorio, por ejemplo crm_python, y dentro un archivo llamado crm.py. La tabla inicial guarda un nombre y datos básicos de contacto. El identificador entero permite referirse a cada registro de forma inequívoca al editarlo o borrarlo.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minute#1 Best Overall
- Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
- Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
- Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
- Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
- 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
import sqlite3
DB_FILE = "crm.db"
def conectar():
# En Python 3.12+, autocommit=False activa el control transaccional
# recomendado para el comportamiento PEP 249.
return sqlite3.connect(DB_FILE, autocommit=False)
def crear_tabla():
with conectar() as con:
con.execute("""
CREATE TABLE IF NOT EXISTS contactos (
id INTEGER PRIMARY KEY,
nombre TEXT NOT NULL,
empresa TEXT,
email TEXT,
telefono TEXT
)
""")
if __name__ == "__main__":
crear_tabla()
print(f"Base de datos lista: {DB_FILE}")
Ejecuta python crm.py (en algunos sistemas, python3 crm.py). SQLite crea crm.db si aún no existe, y CREATE TABLE IF NOT EXISTS evita un error cuando la tabla ya está creada. El bloque with administra la transacción: si termina correctamente, confirma los cambios; si ocurre una excepción, los revierte. Aun así, cerrar explícitamente la conexión es una buena práctica para las operaciones que no usan este patrón.
2. Añadir un contacto de forma segura
Agrega esta función a crm.py. Los signos ? son placeholders posicionales: los valores se envían por separado y no se incorporan a la sentencia SQL mediante concatenación o interpolación.
def agregar_contacto(nombre, empresa=None, email=None, telefono=None):
with conectar() as con:
cursor = con.execute(
"""INSERT INTO contactos (nombre, empresa, email, telefono)
VALUES (?, ?, ?, ?)""",
(nombre, empresa, email, telefono),
)
return cursor.lastrowid
Prueba la función añadiendo al bloque principal, antes del mensaje final, una llamada de ejemplo:
Rank #2
- 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
- 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
- Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
- 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
- What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
nuevo_id = agregar_contacto(
"Ada Lovelace", "Analytical Engines", "ada@example.com", "555-0100"
)
print(f"Contacto añadido con ID {nuevo_id}")
Al guardar los cambios en la conexión, el registro queda en el archivo y estará disponible al volver a ejecutar el programa. Usa direcciones y datos ficticios en pruebas.
3. Listar y buscar contactos
Listar todos
Recupera las filas con fetchall() y muestra cada campo. La ordenación por ID hace que la salida sea predecible.
def listar_contactos():
with conectar() as con:
return con.execute(
"""SELECT id, nombre, empresa, email, telefono
FROM contactos ORDER BY id"""
).fetchall()
def mostrar_contactos(filas):
if not filas:
print("No hay contactos.")
return
for contacto in filas:
print(contacto)
Buscar por nombre
Para una búsqueda parcial, usa LIKE y pasa el patrón como valor. El carácter % permite coincidencias antes o después del texto escrito.
Rank #3
- Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
- Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
- Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
- Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
- What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.
def buscar_por_nombre(texto):
patron = f"%{texto}%"
with conectar() as con:
return con.execute(
"""SELECT id, nombre, empresa, email, telefono
FROM contactos WHERE nombre LIKE ? ORDER BY nombre""",
(patron,),
).fetchall()
Por ejemplo, mostrar_contactos(buscar_por_nombre("Ada")) muestra las filas cuyos nombres contienen “Ada”. La entrada sigue siendo un parámetro, no parte del SQL.
4. Editar un contacto por su ID
El ID indica qué fila modificar. La función devuelve el número de filas afectadas para que puedas distinguir una actualización real de una búsqueda sin coincidencias.
Free tools Windows power users keep installed
One-click scans. No signup required.
def actualizar_email(contacto_id, nuevo_email):
with conectar() as con:
cursor = con.execute(
"UPDATE contactos SET email = ? WHERE id = ?",
(nuevo_email, contacto_id),
)
return cursor.rowcount
Ejemplo de uso: actualizar_email(1, "ada.nueva@example.com"). Si devuelve 0, no se encontró un registro con ese ID; si devuelve 1, se afectó una fila. El bloque with confirma la modificación al finalizar sin errores.
Rank #4
- Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
- Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
- Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
- Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
- Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft
5. Eliminar un contacto
La eliminación también debe identificar la fila por ID. Comprueba el número de filas afectadas antes de informar que el contacto se borró.
def eliminar_contacto(contacto_id):
with conectar() as con:
cursor = con.execute(
"DELETE FROM contactos WHERE id = ?",
(contacto_id,),
)
return cursor.rowcount
Una llamada como eliminar_contacto(1) devuelve 1 cuando encuentra y elimina ese contacto, o 0 si no existe. No ejecutes una eliminación sin una condición identificadora: podrías borrar más datos de los pretendidos.
Por qué usar parámetros y cómo revertir cambios
Los parámetros evitan tratar entradas como fragmentos de código SQL. La documentación oficial de Python indica: “Always use placeholders instead of string formatting to bind Python values to SQL statements, to avoid SQL injection attacks.” En este ejemplo se usan placeholders posicionales ?; sqlite3 también permite parámetros con nombre, que pueden ser más legibles cuando una consulta contiene varios valores.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteBest Value
- 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
- Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
- Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
- HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
- What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.
Con autocommit=False, los cambios de cada operación quedan dentro de una transacción y el administrador de contexto confirma al terminar normalmente. Si una operación más amplia realiza varios cambios y falla, puedes revertirlos con rollback() antes de cerrar la conexión:
con = conectar()
try:
con.execute("UPDATE contactos SET empresa = ? WHERE id = ?", ("Nueva empresa", 1))
# Añade aquí otras operaciones que deban formar una sola unidad.
con.commit()
except Exception:
con.rollback()
raise
finally:
con.close()
No mezcles sin explicación este enfoque con el modo heredado de transacciones: los valores predeterminados y el comportamiento histórico dependen de la versión de Python. Si trabajas con una versión anterior a Python 3.12, consulta la documentación de esa versión y adapta la configuración en lugar de asumir que acepta el argumento autocommit.
6. Comprobar el ciclo CRUD
Con las funciones definidas, puedes hacer una comprobación manual desde el bloque if __name__ == "__main__" o llamarlas desde una sesión interactiva de Python:
- Ejecuta
crear_tabla()para preparar la base local. - Llama a
agregar_contacto(...)y anota el ID que devuelve. - Ejecuta
mostrar_contactos(listar_contactos())y verifica que aparece la fila. - Busca parte del nombre con
buscar_por_nombre("Ada"). - Actualiza el correo con el ID anotado y vuelve a listar para comprobar el cambio.
- Elimina ese ID y lista otra vez para verificar que ya no aparece.
Al cerrar y volver a abrir el programa, los registros no eliminados deberían seguir en crm.db. Para empezar de cero en una prueba, detén el programa y elimina ese archivo; al volver a ejecutarlo se creará una base vacía.
Qué falta para convertirlo en un CRM de uso real
Una tabla única es suficiente para aprender el flujo básico, pero no cubre necesidades más amplias. Mantén empresas, actividades o notas en tablas separadas si cada contacto puede tener varias, y enlázalas mediante claves; ese diseño evita repetir datos y requiere consultas adicionales. También tendrías que decidir cómo validar entradas, presentar una interfaz, proteger datos, gestionar acceso, hacer copias de seguridad y atender el uso simultáneo. SQLite resuelve el almacenamiento local del ejemplo; esas capacidades no aparecen automáticamente por usarla.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

