in_ - Python dicts en sqlalchemy
sqlalchemy sqlite (3)
El SQLAlchemy PickleType está destinado exactamente para esto.
class SomeEntity(Base):
__tablename__ = ''some_entity''
id = Column(Integer, primary_key=True)
attributes = Column(PickleType)
# Just set the attribute to save it
s = SomeEntity(attributes={''baked'': ''beans'', ''spam'': ''ham''})
session.add(s)
session.commit()
# If mutable=True on PickleType (the default) SQLAlchemy automatically
# notices modifications.
s.attributes[''parrot''] = ''dead''
session.commit()
Puede cambiar el mecanismo de serialización cambiando el selector con otra cosa que tenga métodos de dumps()
y de loads()
. El mecanismo de almacenamiento subyacente subclasificando PickleType y anulando impl attritbute:
class TextPickleType(PickleType):
impl = Text
import json
class SomeOtherEntity(Base):
__tablename__ = ''some_other_entity''
id = Column(Integer, primary_key=True)
attributes = Column(TextPickleType(pickler=json))
Me gustaría cargar / guardar un dictado en / desde mi base de datos sqlite, pero estoy teniendo algunos problemas para encontrar una manera simple de hacerlo. Realmente no necesito poder filtrar, etc., en función del contenido, por lo que una conversión simple a / desde la cadena está bien.
La siguiente mejor cosa sería las claves externas. Por favor, no publique enlaces a grandes ejemplos, mi cabeza explotaría si alguna vez pongo los ojos en esos.
Si necesita mapear una relación 1-N y dict
como dict
lugar de list
, entonces lea Colecciones basadas en diccionario
Pero si te refieres a un campo , entonces lo que puedes hacer es tener un campo DB de tipo cadena, que se asigna a tu objeto Python. Pero en el mismo objeto de Python, proporciona una propiedad que será una especie de proxy para este campo de cadena asignada de tipo dict (). Ejemplo de código (no probado):
class MyObject(object):
# fields (mapped automatically by sqlalchemy using mapper(...)
MyFieldAsString = None
def _get_MyFieldAsDict(self):
if self.MyFieldAsString:
return eval(self.MyFieldAsString)
else:
return {} # be careful with None and empty dict
def _set_MyFieldAsDict(self, value):
if value:
self.MyFieldAsString = str(value)
else:
self.MyFieldAsString = None
MyFieldAsDict = property(_get_MyFieldAsDict, _set_MyFieldAsDict)
Puede crear un tipo personalizado subclasificando sqlalchemy.types.TypeDecorator
para manejar la serialización y la deserialización a texto.
Una implementación podría parecer
import json
import sqlalchemy
from sqlalchemy.types import TypeDecorator
SIZE = 256
class TextPickleType(TypeDecorator):
impl = sqlalchemy.Text(SIZE)
def process_bind_param(self, value, dialect):
if value is not None:
value = json.dumps(value)
return value
def process_result_value(self, value, dialect):
if value is not None:
value = json.loads(value)
return value
Ejemplo de uso:
class SomeModel(Base):
__tablename__ = ''the_table''
id = Column(Integer, primary_key=True)
json_field = Column(TextPickleType())
s = SomeEntity(json_field={''baked'': ''beans'', ''spam'': ''ham''})
session.add(s)
session.commit()
Esto se describe en un ejemplo en los documentos de SQLAlchemy , que también muestra cómo rastrear las mutaciones de ese diccionario.
Este enfoque debería funcionar para todas las versiones de Python, mientras que el simple hecho de pasar json
como valor al argumento de PickleType
no funcionará correctamente, como lo señala AlexGrönholm en su comentario sobre otra respuesta.