Uniquement pour les sélections et les insertions
Eh bien, pour sélectionner, vous pouvez utiliser :
>>> from sqlalchemy import func
>>> session = (...)
>>> (...)
>>> engine = create_engine('sqlite:///:memory:', echo=True)
>>> q = session.query(Model.id).filter(Model.some == func.HEX('asd'))
>>> print q.statement.compile(bind=engine)
SELECT model.id
FROM model
WHERE model.some = HEX(?)
Pour insérer :
>>> from sqlalchemy import func
>>> session = (...)
>>> (...)
>>> engine = create_engine('sqlite:///:memory:', echo=True)
>>> m = new Model(hash=func.HEX('asd'))
>>> session.add(m)
>>> session.commit()
INSERT INTO model (hash) VALUES (HEX(%s))
Une meilleure approche :colonne personnalisée qui convertit les données à l'aide de fonctions sql
Mais, je pense que le mieux pour vous est un personnalisé chronique sur sqlalchemy
en utilisant n'importe quel process_bind_param
, process_result_value
, bind_expression
et column_expression
voir cet exemple .
Vérifiez ce code ci-dessous, il crée une colonne personnalisée qui, je pense, correspond à vos besoins :
from sqlalchemy.types import VARCHAR
from sqlalchemy import func
class HashColumn(VARCHAR):
def bind_expression(self, bindvalue):
# convert the bind's type from String to HEX encoded
return func.HEX(bindvalue)
def column_expression(self, col):
# convert select value from HEX encoded to String
return func.UNHEX(col)
Vous pouvez modéliser votre table comme :
from sqlalchemy import Column, types
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Model(Base):
__tablename__ = "model"
id = Column(types.Integer, primary_key=True)
col = Column(HashColumn(20))
def __repr__(self):
return "Model(col=%r)" % self.col
Quelques utilisations :
>>> (...)
>>> session = create_session(...)
>>> (...)
>>> model = Model(col='Iuri Diniz')
>>> session.add(model)
>>> session.commit()
cela génère cette requête :
INSERT INTO model (col) VALUES (HEX(?)); -- ('Iuri Diniz',)
Plus d'utilisation :
>>> session.query(Model).first()
Model(col='Iuri Diniz')
cela génère cette requête :
SELECT
model.id AS model_id, UNHEX(model.col) AS model_col
FROM model
LIMIT ? ; -- (1,)
Un peu plus :
>>> session.query(Model).filter(Model.col == "Iuri Diniz").first()
Model(col='Iuri Diniz')
cela génère cette requête :
SELECT
model.id AS model_id, UNHEX(model.col) AS model_col
FROM model
WHERE model.col = HEX(?)
LIMIT ? ; -- ('Iuri Diniz', 1)
Extra :colonne personnalisée qui convertit les données à l'aide de types Python
Peut-être souhaitez-vous utiliser de beaux types personnalisés et que vous voulez le convertir entre python et la base de données.
Dans l'exemple suivant, je convertis les UUID entre python et la base de données (le code est basé sur ceci lien ):
import uuid
from sqlalchemy.types import TypeDecorator, VARCHAR
class UUID4(TypeDecorator):
"""Portable UUID implementation
>>> str(UUID4())
'VARCHAR(36)'
"""
impl = VARCHAR(36)
def process_bind_param(self, value, dialect):
if value is None:
return value
else:
if not isinstance(value, uuid.UUID):
return str(uuid.UUID(value))
else:
# hexstring
return str(value)
def process_result_value(self, value, dialect):
if value is None:
return value
else:
return uuid.UUID(value)