Red de conocimiento informático - Material del sitio web - Basado en la plataforma de análisis de datos Pandas, ¿se debe utilizar el ORM de SqlAlchemy para la conexión de datos?

Basado en la plataforma de análisis de datos Pandas, ¿se debe utilizar el ORM de SqlAlchemy para la conexión de datos?

Primer uso:

desde sqlalchemy import create_engine

desde sqlalchemy.orm import sessionmaker

DB_CONNECT_STRING = 'mysql mysqldb:// root : 123@localhost/ooxx?charset=utf8'

motor = create_engine(DB_CONNECT_STRING, echo=True)

DB_Session = sessionmaker(bind=motor)

create_engine() Devuelve el parámetro de eco del motor de la base de datos True para mostrar cada instrucción SQL ejecutada y el entorno está cerrado

sessionmaker() La conexión de la base de datos de la instancia de la clase de base de datos registra algunos datos de la consulta y decide ejecutar SQL La declaración se inicializa mediante el grupo de conexiones de base de datos automantenido de SQLAlchemy (5 conexiones predeterminadas) y la inicialización BaseHandler inicialize() de Tornado:

clase BaseHandler(tornado.web.RequestHandler):

def inicializar (self):

self.session = models.DB_Session()

def on_finish(self):

self.session.close()

El servidor web dijo que usar sqlalchemy.orm.scoped_session puede garantizar que cada subproceso obtenga una sesión, pero el propio Tornado puede causar problemas al usar un solo subproceso asincrónico y no lo usa

Usar la sesión para ejecutar SQL:

session.execute('crear base de datos abc')

imprimir sesión.execute('mostrar bases de datos').fetchall()

session.execute('use abc ')

# Crear tabla de usuarios brevemente

imprimir session.execute('select * del usuario donde id = 1').first()

print session.execute('select * from user where id = :id', {'id': 1}).first()

No hay diferencia si usas MySQL -Python directamente; el método ORM usa SQLAlchemy Weiyuan

En la tabla de definición:

de sqlalchemy import Column

de sqlalchem;

y.types importa CHAR, Entero, Cadena

desde sqlalchemy.ext.declarative import declarative_base

BaseModel = declarative_base()

def init_db():

p>

BaseModel.metadata.create_all(motor)

def drop_db():

BaseModel.metadata.drop_all(motor)

clase Usuario( Modelo Base):

__tablename__ = 'usuario'

id = Columna(Entero, clave_primaria=Verdadero)

nombre = Columna(CHAR( 30)) # o Column(String(30))

init_db()

declarative_base() crea una clase BaseModel y la asocia con la tabla

Usuario clase ejemplo__tablename__ atributo base de datos El nombre de la tabla tiene dos campos y es un número entero de 30 caracteres. Explicaré algunos de sus parámetros.

BaseModel.metadata.create_all(motor) encuentra la clase BaseModel y la crea. algunas tablas en la base de datos; drop_all() elimina alguna tabla

Luego comienza a usar la tabla:

de sqlalchemy import func, or_, not_

usuario = Usuario (nombre='a')

sesión.add(usuario)

usuario = Usuario(nombre='b')

sesión.add(usuario)

usuario = Usuario( nombre='a')

sesión.add(usuario)

usuario = Usuario()

sesión .add(usuario)

session.commit()

consulta = session.query(Usuario)

imprimir consulta # Mostrar sentencia SQL

imprimir consulta.declaración # Igual que

para el usuario en la consulta: # Consulta transversal

imprimir usuario.nombre

imprimir consulta.all() # Retornar imagen de lista similar

imprimir consulta .first().name # Guardar el primer registro() y devolver Ninguno

# imprimir consulta.one().name # Guardar o registrar en fila y tirar excepción

print query.filter(User .id == 2).first().name

print query.get(2).name #Obtener la clave principal equivale a la oración

imprimir query.filter('id = 2').first().name # Soporta cadenas

query2 = session.query(User.name)

imprimir

query2.all() # Tupla por línea

imprimir query2.limit(1).all() # Devolver 1 registro

imprimir query2.offset(1).all() # Se devuelve el segundo registro

print query2.order_by(User.name).all()

print query2.order_by('name').all()

imprimir consulta2.order_by(User.name.desc()).all()

imprimir consulta2.order_by('nombre desc').all()

imprimir sesión. query(User.id).order_by(User.name.desc(), User.id).all()

imprimir consulta2.filter(User.id == 1).scalar() #Registro el elemento del registro devuelto

print session.query('id').select_from(User).filter('id = 1').scalar()

print query2. filter(User.id gt; 1, User.name != 'a').scalar() # and

query3 = query2.filter(User.id gt; 1) # Empalmar filtros y

consulta3 = consulta3.filter(Usuario.nombre!= 'a')

imprimir consulta3.scalar()

imprimir consulta2.filtro(o_( Usuario.id == 1, User.id == 2)).all() # o

imprimir consulta2.filter(User.id.in_((1, 2))).all() # en

consulta4 = sesión.consulta(Usuario.id)

imprimir consulta4.filtro(Usuario.nombre == Ninguno).scalar()

imprimir consulta4.filtro ('el nombre es nulo').scalar()

imprimir consulta4.filter(not_(User.name == Ninguno)).all() # no

imprimir consulta4.filter (Usuario.nombre!= Ninguno).all()

imprimir consulta4.count()

imprimir sesión.query(func.count('*')). ).scalar()

imprimir sesión.query(func.count('1')).select_from(Usuario).scalar()

imprimir sesión.query( func.count (User.id)).scalar()

imprimir sesión.query(func.count('*')).filter(User.id gt; 0).scalar

() # filter() contiene Usuario y necesita especificar la tabla

print session.query(func.count('*')).filter(User.name == 'a').limit( 1). escalar() == 1 # Utilice limit() para limitar el retorno del recuento()

print session.query(func.sum(User.id)).scalar()

print session.query(func.now()).scalar() # func seguido de cualquier nombre de función debe ser compatible con la base de datos

print session.query(func.current_timestamp()).scalar ()

imprimir sesión.query(func.md5(Usuario.nombre)).filter(Usuario.id == 1).scalar()

query.filter(Usuario. id == 1). actualizar({Usuario.nombre: 'c'})

usuario = query.get(1)

imprimir usuario.nombre

user.name = ' d'

session.flush() # Escribir en la base de datos y enviar

imprimir query.get(1).name

session.delete(usuario)

session.delete(usuario)

p>

session.flush()

imprimir consulta.get(1)

sesión.rollback()

imprimir consulta.get(1) .nombre

query.filter(User.id == 1).delete()

session.commit()

print query.get(1)

2. Conocimientos avanzados

1) Cómo insertar lotes datos en lotes

Utilice un método que no sea ORM:

session.execute(

User.__table__.insert(),

[ {'nombre': `randint(1, 100)`, 'edad': randint(1, 100)} para i en xrange(10000)]

)

sesión. commit()

Cómo insertar datos por lotes en lotes

Usar un método que no sea ORM:

session.execute(

User. __table__.insert(),

[{'nombre': `randint(1, 100)`, 'edad': randint(1, 100)} para i en xrange(10000)]

)

session.commit()

Insertar 10,000 registros en lotes Completado en segundos; el estilo ORM lleva tiempo

2) Cómo agregar un prefijo a la declaración SQL ejecutada

Utilice consultas como prefix_with():

session.query (User.name).prefix_with('HIGH_PRIORITY').all()

sesión

.execute(User.__table__.insert().prefix_with('IGNORE'), {'id': 1, 'name': '1'})

3) Cómo reemplazar el registro de clave principal

Utilice session.merge() en lugar de session.add() De hecho, SELECCIONE ACTUALIZACIÓN:

usuario = Usuario(id=1, nombre='ooxx')

session .merge(user)

session.commit()

O usar MySQL INSERT... EN LA ACTUALIZACIÓN DE CLAVE DUPLICADA necesita usar el decorador @compiles. un poco difícil de entender Eche un vistazo a: "SQLAlchemy ON DUPLICATE" KEY UPDATE》 sqlalchemy_mysql_ext

4) Cómo usar enteros con signo

Usando MySQL:

. de sqlalchemy.dialects.mysql import INTEGER

id = Column(INTEGER(unsigned=True), Primary_key=True)

5) El nombre del atributo del modelo requiere administración del nombre del campo de la tabla

Encontré un requisito extraño: la tabla del sistema contiene el campo from. Las palabras clave de Python pueden procesarse:

from_ = Column('from', CHAR(10))

6) Cómo obtener el grado de campo

Imaginación compleja de columnas Es problemático obtener User.name Ejemplo:

User.name.property.columns[0].type. longitud

7) Cómo especificar el uso de codificación InnoDB y UTF-8

La modificación simple de la configuración de la base de datos predeterminada requiere la especificación del código:

clase Usuario( BaseModel):

__table_args__ = {

'mysql_engine' : 'InnoDB',

'mysql_charset': 'utf8'

}

MySQL 5.5 comienza a soportar el almacenamiento de caracteres codificados UTF-8 de 4 bytes que vienen con iOS emoji (carácter?) pertenece a la especie

Código de superficie de configuración de tabla cambio utf8 cambio de conjunto de caracteres utf8mb4DB_CONNECT_STRING

La configuración de biblioteca o campo son sentencias SQL escritas por usted mismo. Para obtener más información, consulte "Cómo admitir Unicode completo" en bases de datos MySQL》

Se recomienda utilizar utf8mb4 en lugar de. utf8. El primero es más lento y el índice ocupa más espacio

8) Cómo establecer restricciones de clave externa

desde randint de importación aleatoria

desde sqlalchemy import ForeignKey

clase Usuario(BaseModel):

__tablename__ = 'usuario'

id = Columna(Entero, clave_primaria= Verdadero)

edad = Columna(Entero)

clase Amistad(ModeloBase):

>__tablename__ = 'amistad'

id = Columna(Entero, clave_primaria=Verdadero)

user_id1 = Columna(Entero, ForeignKey('usuario.id'))

user_id2 = Columna(Integer, ForeignKey('user.id'))

para i en xrange(100):

session.add(User(age=randint(1 , 100)))

session.flush() # o session.commit() se ejecuta antes de acceder al atributo de identificación de la imagen del usuario (la identificación se incrementa)

para i en xrange (100):

session.add(Amistad(user_id1=randint(1, 100), user_id2=randint(1, 100)))

session.commit()

session.query(User).filter(User.age lt; 50).delete()

Debe ocurrir un error al ejecutar el código:

sqlalchemy. exc.IntegrityError: (IntegrityError) (1451, 'No se puede eliminar o actualizar una fila principal: falla una restricción de clave externa (`ooxx`.`friendship`, CONSTRAINT `friendship_ibfk_1` CLAVE EXTRANJERA (`user_id1`) REFERENCIAS `usuario` (` id`)) ') 'DELETE FROM user WHERE user.age lt; (50,) La eliminación original de los datos de la tabla de usuario puede hacer que la clave externa de amistad apunte al registro almacenado real. De forma predeterminada, MySQL rechaza esta operación. RESTRICTInnoDB permite especificar ON DELETE CASCADE SET NULL. El primero elimina el efecto de amistad. Las claves externas de algunos registros de la grabadora se establecen en NULL.

Excepto que la eliminación puede cambiar la clave principal, lo que hace que la clave externa de amistad. deja de ser válido en el ON UPDATE correspondiente y su cambio en CASCADA para actualizar la clave externa correspondiente y eliminarla

Procesamiento de SQLAlchemy:

clase Friendship(BaseModel):

__tablename__ = 'amistad'

id = Columna(Entero, clave_primaria=Verdadero)

user_id1 = Columna( Entero, ForeignKey('usuario.id', ondelete='CASCADE', onupdate ='CASCADE'))

user_id2 = Column(Integer, ForeignKey('user.id', ondelete='CASCADE', onupdate='CASCADE'))

9) Cómo para conectar la tabla

desde sqlalchemy importar distinta

<

p>de sqlalchemy.orm importar aliased

Amigo = aliased(Usuario, nombre='Amigo')

imprimir session.query(User.id).join(Amistad, Usuario. id == Friendship.user_id1).all() # Todos los usuarios amigos

imprimir session.query(distinct(User.id)).join(Friendship, User.id == Friendship.user_id1).all () # Todos los usuarios amigos (eliminar duplicados)

imprimir session.query(User.id).join(Friendship, User.id == Friendship.user_id1).distinct().all() # Igual as

print session.query(Friendship.user_id2).join(User, User.id == Friendship.user_id1).order_by(Friendship.user_id2).distinct().all() # Diferentes usuarios amigos

imprimir session.query(Friendship.user_id2).select_from(User).join(Friendship, User.id == Friendship.user_id1).order_by(Friendship.user_id2).distinct().all() # Igual que unirse pero opuesto al orden autoseleccionado de MySQL de STRAIGHT_JOIN

print session.query(User.id, Friendship.user_id2).join(Friendship, User.id == Friendship.user_id1). all() # Usuarios y sus amigos

print session.query(User.id, Friendship.user_id2).join(Friendship, User.id == Friendship.user_id1).filter(User.id lt; 10).all () # id en 10 usuarios y sus amigos

print session.query(User.id, Friend.id).join(Friendship, User.id == Friendship.user_id1).join (Friend, Friend .id == Friendship.user_id2).all() # Las dos uniones requieren alias porque usan la misma tabla

print session.query(User.id, Friendship.user_id2).outerjoin (Friendship, User.id = = Friendship.user_id1).all() # Usuario y sus amigos (Ninguno para amigos, use la unión izquierda)

-

-