¿Hay alguna manera de definir una columna (clave principal) como UUID en SQLAlchemy si usa PostgreSQL (Postgres)?¿Cómo puedo usar los UUID en SQLAlchemy?
Respuesta
Usted podría intentar escribir un custom type, por ejemplo:
import sqlalchemy.types as types
class UUID(types.TypeEngine):
def get_col_spec(self):
return "uuid"
def bind_processor(self, dialect):
def process(value):
return value
return process
def result_processor(self, dialect):
def process(value):
return value
return process
table = Table('foo', meta,
Column('id', UUID(), primary_key=True),
)
Esto ni siquiera funciona, es solo un trabajo de cortar y pegar del ejemplo de tipo ficticio de los documentos. La respuesta de Tom Willis a continuación es mucho mejor. –
Además de [la respuesta de Florian] (http://stackoverflow.com/questions/183042/how-can-i-use-uuids-in-sqlalchemy/188427#188427), también hay [esta entrada en el blog] (http: //blog.sadphaeton.com/2009/01/19/sqlalchemy-recipeuuid-column.html). Se ve similar, excepto que subclasifica 'types.TypeDecorator' en lugar de' types.TypeEngine'. ¿Alguno de los enfoques tiene una ventaja o desventaja sobre el otro? –
¿No necesita un 'default =?'? p.ej. 'Column ('id', UUID(), primary_key = True, default =
I wrote this y el dominio se ha ido, pero aquí está la tripa ....
Independientemente de cómo mis colegas que realmente se preocupan por la base de datos adecuada sensación de diseño sobre UUID y GUID utilizados para campos clave. A menudo me parece que necesito hacerlo. Creo que tiene algunas ventajas sobre la autoincrementación que hacen que valga la pena.
He estado refinando un tipo de columna UUID durante los últimos meses y creo que finalmente lo tengo sólido.
from sqlalchemy import types
from sqlalchemy.dialects.mysql.base 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)))
creo almacenar en formato binario (16 bytes) debe llegar a ser más eficiente que la representación de cadena (36 bytes?), Y parece que hay algunos indicios de que la indexación 16 bloques de bytes deben ser más eficientes en MySQL de cuerdas No esperaría que sea peor de todos modos.
Una desventaja que he encontrado es que al menos en phpymyadmin, no puede editar registros porque implícitamente intenta hacer algún tipo de conversión de caracteres para el "select * from table where id = ..." y hay misceláneos problemas de visualización.
Aparte de eso, todo parece funcionar bien, así que lo estoy tirando. Deja un comentario si ves un error evidente con él. Agradezco cualquier sugerencia para mejorarlo.
A menos que me falta algo, la solución anterior funcionará si la base de datos subyacente tiene un tipo de UUID. Si no es así, es probable que obtenga errores cuando se crea la tabla. La solución que se me ocurrió. Mi objetivo era MSSqlServer originalmente y luego fue MySql al final, por lo que creo que mi solución es un poco más flexible, ya que parece funcionar bien en mysql y sqlite. No me he molestado en verificar postgres todavía.
Esto debería haber sido elegido como la respuesta, supongo que lo publicaste mucho más tarde. –
Sí, lo publiqué después de ver las referencias de la respuesta de Jacob. –
Tenga en cuenta que si usa la versión 0.6 o superior, la instrucción de importación de MSBinary en la solución de Tom debe cambiarse a "de sqlalchemy.dialects.mysql.base import MSBinary". Fuente: http://www.mail-archive.com/[email protected]/msg18397.html –
Consulte también la receta Backend-agnostic GUID Type en la documentación de SQLAlchemy para tipos de columnas.
En caso de que a alguien le interesa, he estado usando respuesta Tom Willis, pero no encontraron útil añadir una cadena a la conversión uuid.UUID en el método process_bind_param
class UUID(types.TypeDecorator):
impl = types.LargeBinary
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 isinstance(value, basestring):
return uuid.UUID(value).bytes
elif value:
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
Aquí es un enfoque basado en la Backend agnostic GUID desde los documentos de SQLAlchemy, pero utilizando un campo BINARIO para almacenar los UUID en bases de datos no postgresql.
import uuid
from sqlalchemy.types import TypeDecorator, BINARY
from sqlalchemy.dialects.postgresql import UUID as psqlUUID
class UUID(TypeDecorator):
"""Platform-independent GUID type.
Uses Postgresql's UUID type, otherwise uses
BINARY(16), to store UUID.
"""
impl = BINARY
def load_dialect_impl(self, dialect):
if dialect.name == 'postgresql':
return dialect.type_descriptor(psqlUUID())
else:
return dialect.type_descriptor(BINARY(16))
def process_bind_param(self, value, dialect):
if value is None:
return value
else:
if not isinstance(value, uuid.UUID):
if isinstance(value, bytes):
value = uuid.UUID(bytes=value)
elif isinstance(value, int):
value = uuid.UUID(int=value)
elif isinstance(value, str):
value = uuid.UUID(value)
if dialect.name == 'postgresql':
return str(value)
else:
return value.bytes
def process_result_value(self, value, dialect):
if value is None:
return value
if dialect.name == 'postgresql':
return uuid.UUID(value)
else:
return uuid.UUID(bytes=value)
¿Cuál sería el uso de esto? – codeninja
He utilizado el UUIDType
del SQLAlchemy-Utils
paquete: http://sqlalchemy-utils.readthedocs.org/en/latest/data_types.html#module-sqlalchemy_utils.types.uuid
Actualmente estoy tratando de usar esto, el problema es que me sale un error: 'raise InvalidStatus (" notfound: {k}. (Cls = {cls}) ". Format (k = k, cls = cls))' 'alchemyjsonschema.InvalidStatus: notfound: BINARY (16). (cls =
Si está satisfecho con la columna una 'cadena' que tiene un valor UUID, aquí va una solución sencilla:
def generate_uuid():
return str(uuid.uuid4())
class MyTable(Base):
__tablename__ = 'my_table'
uuid = Column(String, name="uuid", primary_key=True, default=generate_uuid)
- 1. ¿Puedo usar SQLAlchemy con Cassandra CQL?
- 2. SQLAlchemy: Operando en los resultados
- 3. UUID en Rails3
- 4. Configurando Django para usar SQLAlchemy
- 5. Android Bluetooth ¿Dónde puedo obtener UUID?
- 6. SQLalchemy especifica qué índice usar
- 7. UUID en CouchDB
- 8. ¿Cómo puedo usar varias bases de datos en la misma solicitud en Cherrypy y SQLAlchemy?
- 9. ¿Debo usar UUID para recursos en mi API pública?
- 10. ¿Puedo asignar valores en RowProxy usando sqlalchemy?
- 11. ¿Cómo puedo perfilar una aplicación con SQLAlchemy?
- 12. ¿Cómo hacer un UUID en DynamoDB?
- 13. ¿Cómo puedo acelerar mi función MySQL UUID v4 almacenada?
- 14. ¿Cuándo es apropiado usar UUID para un proyecto web?
- 15. cómo serializar boost :: uuids :: uuid
- 16. ¿Vale la pena usar sqlalchemy-migrate?
- 17. ¿Cómo almacenar uuid como número?
- 18. ¿Es seguro usar SQLalchemy con gevent?
- 19. Obtener UUID sin iTunes
- 20. XSLT generar UUID
- 21. UUID con Play Framework
- 22. ¿Cómo puedo verificar los tipos de datos de columna en el SQLAlchemy ORM?
- 23. PHP preg_match UUID v4
- 24. ¿Qué son exactamente los metadatos en SQLAlchemy?
- 25. UUID para aplicación en IOS5
- 26. ¿Cómo puedo usar HTML5 en todos los navegadores, incluido IE7,8?
- 27. ¿Cómo puedo usar los frascos externos en JBoss 7?
- 28. ¿Cómo puedo usar los atributos de datos HTML5 en XHTML?
- 29. ¿Cómo puedo usar la sintaxis Bash en los objetos Makefile?
- 30. ¿Cómo puedo optimizar esta consulta producida por SQLAlchemy?
Desafortunadamente [Tipo de GUID independiente del backend] (http://docs.sqlalchemy.org/en/rel_0_9/core/custom_types.html?highlight=guid#backend-agnostic-guid-type) de la documentación de SQLAlchemy para tipos de columnas no parece para trabajar con claves primarias en motores de base de datos SQLite. No es tan ecuménico como esperaba. – adamek