tutorial query column mysql sqlalchemy uuid pylons

mysql - query - sqlalchemy selectable



ID aleatorios en sqlalchemy(pilones) (4)

Estoy usando pylons y sqlalchemy y me preguntaba cómo podría tener algunos id. De randoms como primary_key.


la mejor manera es usar UUID generados aleatoriamente:

import uuid id = uuid.uuid4()

Los tipos de datos de uuid están disponibles de forma nativa en algunas bases de datos, como Postgresql (SQLAlchemy tiene un tipo de datos de uuid PG nativo para este fin, en 0.5 se llama sqlalchemy.databases.postgres.PGUuid ). También debería poder almacenar un uuid en cualquier campo CHAR de 16 bytes (aunque no he probado esto específicamente en MySQL u otros).


Yo uso este patrón y funciona bastante bien. fuente

from sqlalchemy import types from sqlalchemy.databases.mysql import MSBinary from sqlalchemy.schema import Column import uuid class UUID(types.TypeDecorator): impl = MSBinary def __init__(self): self.impl.length = 16 types.TypeDecorator.__init__(self,length=self.impl.length) def process_bind_param(self,value,dialect=None): if value and isinstance(value,uuid.UUID): return value.bytes elif value and not isinstance(value,uuid.UUID): raise ValueError,''value %s is not a valid uuid.UUID'' % value else: return None def process_result_value(self,value,dialect=None): if value: return uuid.UUID(bytes=value) else: return None def is_mutable(self): return False id_column_name = "id" def id_column(): import uuid return Column(id_column_name,UUID(),primary_key=True,default=uuid.uuid4) #usage my_table = Table(''test'',metadata,id_column(),Column(''parent_id'',UUID(),ForeignKey(table_parent.c.id)))

Aunque creo que zzzeek es el autor de sqlalchemy, entonces si esto está mal lo sabría, y yo lo escucharía.


O con el mapeo de ORM:

import uuid from sqlalchemy import Column, Integer, String, Boolean def uuid_gen(): return str(uuid.uuid4()) Base = declarative_base() class Device(Base): id = Column(String, primary_key=True, default=uuid_gen)

Esto lo almacena como una cadena que proporciona una mejor compatibilidad con la base de datos. Sin embargo, pierde la capacidad de la base de datos para almacenar y usar el uuid de manera más óptima.


Años más tarde con este problema otra vez, así que compartiré mi respuesta actual. Terminé basándome en el tipo de GUID agnóstico de Backend pero quería usar binary en lugar de CHAR (32). También quería tratar cadenas hexagonales directamente en lugar de objetos UUID para imprimir fácilmente en el usuario / url.

import binascii import uuid from sqlalchemy.types import TypeDecorator, BINARY class GUID(TypeDecorator): impl = BINARY def load_dialect_impl(self, dialect): return dialect.type_descriptor(BINARY(16)) def process_bind_param(self, value, dialect): if value is None: return value if not isinstance(value, bytes): if isinstance(value, uuid.UUID): value = value.bytes elif isinstance(value, str): value = binascii.unhexlify(value) else: raise TypeError(''Invalid GUID value.'') return value def process_result_value(self, value, dialect): if value is None: return value return binascii.hexlify(value).decode(''ascii'')

También hice una función auxiliar para ''ordenar'' el UUID para mejorar la eficiencia de indexación en base a esta publicación de blog . Si está utilizando MySQL 8, consulte UUID_TO_BIN () con el indicador de intercambio y BIN_TO_UUID () en su lugar.

def order_uuid(uuid): uuid_str = str(uuid).replace(''-'', '''') ordered_uuid = ''''.join([uuid_str[12:16], uuid_str[8:12], uuid_str[0:8], uuid_str[16:]]) return ordered_uuid def revert_order_uuid(o_uuid_str): original_uuid_str = ''''.join([o_uuid_str[8:16], o_uuid_str[4:8], o_uuid_str[0:4], o_uuid_str[16:]]) return uuid.UUID(original_uuid_str)