Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Python-Sqlalchemy-Binärspaltentyp HEX() und UNHEX()

Nur für Selects und Inserts

Nun, für select könnten Sie verwenden:

>>> 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(?)

Zum Einfügen:

>>> 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))

Ein besserer Ansatz:Benutzerdefinierte Spalte, die Daten mithilfe von SQL-Funktionen konvertiert

Aber ich denke, das Beste für Sie ist ein Benutzerdefiniert Kolumne über sqlalchemy mit einem beliebigen process_bind_param , process_result_value , bind_expression und column_expression siehe dieses Beispiel .

Überprüfen Sie diesen Code unten, er erstellt eine benutzerdefinierte Spalte, die meiner Meinung nach Ihren Anforderungen entspricht:

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)

Sie könnten Ihre Tabelle wie folgt modellieren:

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

Etwas Verwendung:

>>> (...)
>>> session = create_session(...)
>>> (...)
>>> model = Model(col='Iuri Diniz')
>>> session.add(model)
>>> session.commit()

dies gibt diese Abfrage aus:

INSERT INTO model (col) VALUES (HEX(?)); -- ('Iuri Diniz',)

Mehr Verwendung:

>>> session.query(Model).first()
Model(col='Iuri Diniz')

dies gibt diese Abfrage aus:

SELECT 
    model.id AS model_id, UNHEX(model.col) AS model_col 
FROM model 
LIMIT ? ; -- (1,)

Etwas mehr:

>>> session.query(Model).filter(Model.col == "Iuri Diniz").first()
Model(col='Iuri Diniz')

dies gibt diese Abfrage aus:

SELECT 
    model.id AS model_id, UNHEX(model.col) AS model_col 
FROM model 
WHERE model.col = HEX(?) 
LIMIT ? ; -- ('Iuri Diniz', 1)

Extra:Benutzerdefinierte Spalte, die Daten mithilfe von Python-Typen konvertiert

Vielleicht möchten Sie einen schönen benutzerdefinierten Typ verwenden und es zwischen Python und der Datenbank konvertieren möchten.

Im folgenden Beispiel konvertiere ich UUIDs zwischen Python und der Datenbank (der Code basiert auf diesem link ):

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)