sql >> Database teknologi >  >> RDS >> Mysql

Python-Sqlalchemy binær kolonnetype HEX() og UNHEX()

Kun for udvalgte og indsæt

Nå, for at vælge kan du bruge:

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

Til indsættelse:

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

En bedre tilgang:Brugerdefineret kolonne, der konverterer data ved at bruge sql-funktioner

Men jeg tror, ​​det bedste for dig er en brugerdefineret kolonne om sqlalchemy ved at bruge en hvilken som helst process_bind_param , process_result_value , bind_expression og column_expression se dette eksempel .

Tjek denne kode nedenfor, den laver en brugerdefineret kolonne, som jeg synes passer til dine behov:

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)

Du kan modellere dit bord som:

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

Noget brug:

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

dette udløser denne forespørgsel:

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

Mere brug:

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

dette udløser denne forespørgsel:

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

Lidt mere:

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

dette udløser denne forespørgsel:

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

Ekstra:Tilpasset kolonne, der konverterer data ved hjælp af pythontyper

Måske vil du bruge en smuk brugerdefineret type og ønsker at konvertere det mellem python og databasen.

I det følgende eksempel konverterer jeg UUID'er mellem python og databasen (koden er baseret på denne 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)


  1. Er mysql_real_escape_string() brudt?

  2. Typekonvertering. Hvad gør jeg med en PostgreSQL OID-værdi i libpq i C?

  3. 4 måder at få databasesamlingen i MariaDB

  4. Sådan vises alle lagrede procedurer i Oracle-databasen