Consumir datos de SQL Server en Python
Tags: pyhton, sqlalchemy, sqlserver
Published: 2022-10-18 03:06:54

En algún momento nos hemos encontrado con la necesidad de consumir datos o comunicarnos con una base de datos en SQL Server desde Django, a pesar que de forma nativa no tenemos soporte, te dejo dos opciones que me han ayudado a realizar dicha tarea. A pesar que existen diferentes herramientas es importante tener en cuenta que es lo que realmente necesitamos por ejemplo un ORM como SQLAlchemy o Peewee o un conector odbc como Pyodbc.

Primero si solo necesitas consumir datos mediante consulta sql o realizar pequeñas modificaciones te recomiendo Pyodbc, este conector no solo te funciona para SQL Server, puedes utilizarlo con MySql, Access, Oracle, Postgresql etc. Lograr conectar tu base de datos mediante ODBC es bastante fácil como veras a continuación:

```
import pyodbc
connection = pyodbc.connect(f'''{SU_DRIVER};SERVER={ip_server};port=1433;
                                   DATABASE={db_name};UID={user_name};
                                   PWD={password};Mars_Connection=Yes;
                                   TrustServerCertificate=yes;''')
cursor =  connection.cursor()

#Consulta para obtener todos los usuarios de la base de datos
consulta = f"""select * from users”””
cursor.execute(consulta)
data = cursor.fetchall()
```

En el segundo escenario necesitamos herramientas mas potentes y ahí es donde los ORMs como SQLAlchemy y Peewee nos ayudan en nuestra tarea de optimizar consultas, ya sea que necesitamos que nuestra aplicación consuma datos SQL Server o que la base de datos de nuestro proyecto se encuentre en dicho motor de base de datos, SQLAlchemy es el ORM que prefieren la gran mayoría de empresas para trabajar con datos no solamente SQL Server si no con MySql, Mariadb, Oracle, Postgresql, Firebird etc. 

SQLAlchemy es un Mapeador Relacional de Objetos ORM (por sus siglas en ingles) esto nos permite crear clases como Producto y Orden y que ambos tengan una lista relacional de instancias, a diferencia de Pyodbc para aprovechar todo el poder de la herramienta debemos de crear clases y establecer las relaciones entre ellas, si existen atributos que no son necesarios para nosotros no es necesario definirlos en el modelo (de momento). El siguiente código es un ejemplo para definir la tabla Users y establecer una conexión con la base de datos.

```
from sqlalchemy import select
from sqlalchemy import create_engine
from sqlalchemy import Column
from sqlalchemy import ForeignKey
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy.orm import Session
from sqlalchemy.orm import declarative_base
from sqlalchemy.orm import relationship

#Linea de conexion
engine = create_engine( f'mssql+pyodbc://{user}:{password} @{ip_server}/{base_datos}?Driver={driver} ',
                            connect_args = {
                                            'TrustServerCertificate':'yes',
                                            'Mars_Connection':'yes'
                                            })

Base = declarative_base()

#Creamos la instancia de la sesión de nuestro servidor
session = Session(engine)

#Definimos la clase usuario con los atributos que necesitamos
class User(Base):
    __tablename__ = "users"
    
    user_name = Column(String(15), primary_key=True)
    name = Column(String(30))
    email = Column(String(100))

    #Representacion del objeto
    def __repr__(self):
        return f"User(user_name={self.user_name!r}, name={self.name!r}”

#Realiza la consulta sql 
stmt = select(User)

for user in session.scalars(stmt):
    print(user)
```
A pesar que el código tiene mas líneas que la versión de Pyodbc, con solo cambiar la línea de conexión a otro motor de base de datos nuestro código y consultas seguirían funcionando de la misma forma.
Estaré escribiendo mas sobre SQLAlchemy en los siguientes posts.