haul package¶
Subpackages¶
Submodules¶
haul.cli module¶
A nifty CLI tool to dump an exported file’s contents for debugging.
Call it like this:
python -m haul.cli /path/to/file.haul
haul.errors module¶
haul.policy module¶
- class haul.policy.BaseRelinkAction(fallback: Optional[haul.policy.BaseRelinkAction] = None)[source]¶
Bases:
object
Base class for new relink actions.
Override
execute()
to return a list of relinked model instances,None
or a literalFalse
to discard the object.- execute(model_cls: Type[django.db.models.base.Model], objects: List[haul.types.ObjectData], policy: haul.policy.ImportPolicy) Sequence[Optional[Union[django.db.models.base.Model, typing_extensions.Literal[False]]]] [source]¶
- fallback: Optional[haul.policy.BaseRelinkAction] = None¶
- class haul.policy.BaseRelinkActionWithFieldsOverwrite(fallback: Optional[haul.policy.BaseRelinkAction] = None, overwrite_fields: Tuple[str, ...] = ())[source]¶
Bases:
haul.policy.BaseRelinkAction
A base relink action class that automatically overwrites model fields set via
overwrite_fields
.- overwrite_fields: Tuple[str, ...] = ()¶
- class haul.policy.ExportPolicy[source]¶
Bases:
object
A behaviour class that defines how to handle objects during export.
- get_attachments(instance: django.db.models.base.Model) List[haul.types.Attachment] [source]¶
Override to add file or stream based attachments to an object. See
Attachment
.
- should_export_object(instance: django.db.models.base.Model)[source]¶
Override to additionally filter objects during export.
- should_follow_reference(instance: django.db.models.base.Model, target: haul.types.ID, field: str)[source]¶
Override to additionally filter FK references during export.
- class haul.policy.ImportPolicy[source]¶
Bases:
object
A behaviour class that defines how to handle objects during import. Override its methods and pass it to
ImportContainer
to customize the behaviour.- postprocess_object_fields(model_cls: Type[django.db.models.base.Model], fields: Dict[str, Any])[source]¶
Called after
relink_object()
and before the relink actions have been applied. You can modify thefields
dict in place here.
- preprocess_object_fields(model_cls: Type[django.db.models.base.Model], fields: Dict[str, Any])[source]¶
Called after objects have been deserialized. You can modify the
fields
dict in place here.
- process_attachment(instance: django.db.models.base.Model, key: Any, stream: IO[bytes])[source]¶
Called for each attachment on a model. This is where you read and process the attachment contents. Note that the stream is not guaranteed to be open after this method exits and is guaranteed to be closed once the
ImportContainer.import()
context exits.
- process_many_to_many(instance: django.db.models.base.Model, field: str) haul.policy.ManyToManyImportAction [source]¶
Called for each M2M relation on a model. You can either return a
ManyToManyImportAction.REPLACE
orManyToManyImportAction.APPEND
here. The default isREPLACE
.
- relink_object(model_cls: Type[django.db.models.base.Model], obj: haul.types.ObjectData) haul.policy.BaseRelinkAction [source]¶
Called to decide how the imported objects should be mapped onto existing objects. This method should return an instance of a
BaseRelinkAction
subclass.The default implementation just returns
RelinkAction.Create()
- class haul.policy.ManyToManyImportAction(value)[source]¶
Bases:
enum.Enum
An enumeration.
- APPEND = 2¶
- REPLACE = 1¶
- class haul.policy.RelinkAction[source]¶
Bases:
object
- class Create(fallback: Optional[haul.policy.BaseRelinkAction] = None, ignore_fields: Tuple[str, ...] = <factory>)[source]¶
Bases:
haul.policy.BaseRelinkAction
A relink action that unconditionally creates new objects.
- execute(model_cls: Type[django.db.models.base.Model], objects: List[haul.types.ObjectData], policy: haul.policy.ImportPolicy) List[Union[django.db.models.base.Model, typing_extensions.Literal[False]]] [source]¶
- ignore_fields: Tuple[str, ...]¶
A list of fields to ignore during import
- class Discard(fallback: Optional[haul.policy.BaseRelinkAction] = None)[source]¶
Bases:
haul.policy.BaseRelinkAction
A relink action that unconditionally discards all objects.
- execute(_model_cls, objects: List[haul.types.ObjectData], policy: haul.policy.ImportPolicy) Sequence[Optional[Union[django.db.models.base.Model, typing_extensions.Literal[False]]]] [source]¶
- class LinkByFields(fallback: Optional[haul.policy.BaseRelinkAction] = None, overwrite_fields: Tuple[str, ...] = (), lookup_fields: Tuple[str, ...] = <factory>)[source]¶
Bases:
haul.policy.BaseRelinkActionWithFieldsOverwrite
A relink action that tries to look up existing objects by a set of fields.
- execute(model_cls: Type[django.db.models.base.Model], objects: List[haul.types.ObjectData], policy: haul.policy.ImportPolicy) Sequence[Optional[Union[django.db.models.base.Model, typing_extensions.Literal[False]]]] [source]¶
- lookup_fields: Tuple[str, ...]¶
A list of fields to use to look up existing objects
- class LinkByPK(fallback: Optional[haul.policy.BaseRelinkAction] = None, overwrite_fields: Tuple[str, ...] = ())[source]¶
Bases:
haul.policy.BaseRelinkActionWithFieldsOverwrite
A relink action that tries to map objects by their literal PK value.
This only works if the PKs are same in the source and destination databases.
- execute(model_cls: Type[django.db.models.base.Model], objects: List[haul.types.ObjectData], policy: haul.policy.ImportPolicy) List[Optional[Union[django.db.models.base.Model, typing_extensions.Literal[False]]]] [source]¶
- class LinkToInstance(fallback: Optional[haul.policy.BaseRelinkAction] = None, overwrite_fields: Tuple[str, ...] = (), pk: Optional[Hashable] = None)[source]¶
Bases:
haul.policy.BaseRelinkActionWithFieldsOverwrite
A relink action that links the object to a specific existing object.
- execute(model_cls: Type[django.db.models.base.Model], objects: List[haul.types.ObjectData], policy: haul.policy.ImportPolicy) Sequence[Union[django.db.models.base.Model, typing_extensions.Literal[False]]] [source]¶
- pk: Hashable = None¶
PK of the existing object to link to
- class LogToConsole(fallback: Optional[haul.policy.BaseRelinkAction] = None)[source]¶
Bases:
haul.policy.BaseRelinkAction
A relink action that prints the objects and links them to
None
.- execute(model_cls: Type[django.db.models.base.Model], objects: List[haul.types.ObjectData], policy: haul.policy.ImportPolicy) Sequence[Optional[Union[django.db.models.base.Model, typing_extensions.Literal[False]]]] [source]¶
haul.serializers module¶
Haul uses DRF ModelSerializer
as a base for its serialization.
This means you can use custom Field
and Serializer
objects to serialize and deserialize fields.
- class haul.serializers.DummyField(*args, **kwargs)[source]¶
Bases:
rest_framework.fields.Field
- get_attribute(instance)[source]¶
Given the outgoing object instance, return the primitive value that should be used for this field.
- class haul.serializers.Exporter(*args, **kwargs)[source]¶
Bases:
rest_framework.serializers.ModelSerializer
alias of
haul.serializers.DummyField
- class haul.serializers.ForeignKey(*args, **kwargs)[source]¶
Bases:
rest_framework.fields.Field
- bind(field_name, parent)[source]¶
Initializes the field name and parent for the field instance. Called when a field is added to the parent serializer instance.
- export_policy: haul.policy.ExportPolicy¶
- class haul.serializers.ManyToMany(*args, **kwargs)[source]¶
Bases:
haul.serializers._BaseM2X
- export_policy: haul.policy.ExportPolicy¶
- weak = False¶
- class haul.serializers.ReverseForeignKey(*args, **kwargs)[source]¶
Bases:
haul.serializers._BaseM2X
- export_policy: haul.policy.ExportPolicy¶
- weak = True¶
haul.types module¶
- class haul.types.Attachment(id: str, key: Any, content_provider: Union[Callable[[], BinaryIO], NoneType] = None, _container_stream: Union[BinaryIO, NoneType] = None)[source]¶
Bases:
object
- content_provider: Optional[Callable[[], BinaryIO]] = None¶
- id: str¶
- key: Any¶
- class haul.types.ContainerFormat(value)[source]¶
Bases:
enum.Enum
An enumeration.
- COMPRESSED_ZIP = 2¶
- NON_COMPRESSED_ZIP = 3¶
- YAML = 1¶
- class haul.types.ID(kind: str, pk: Any)[source]¶
Bases:
object
- classmethod deserialize(s: Any) haul.types.ID [source]¶
- classmethod from_object(obj: django.db.models.base.Model) haul.types.ID [source]¶
- kind: str¶
- static kind_for_model(obj: Union[django.db.models.base.Model, Type[django.db.models.base.Model]])[source]¶
- pk: Any¶
- yaml_tag = 'ID'¶
- class haul.types.ObjectData(id: haul.types.ID, serialized_data: Dict[str, Any], fields: Union[Dict[str, Any], NoneType] = None, refs: List[haul.types.Ref] = <factory>, refers_to: Set[haul.types.ID] = <factory>, attachments: List[haul.types.Attachment] = <factory>)[source]¶
Bases:
object
- add_reference(ref: haul.types.Ref)[source]¶
- attachments: List[haul.types.Attachment]¶
- fields: Optional[Dict[str, Any]] = None¶
- id: haul.types.ID¶
- refers_to: Set[haul.types.ID]¶
- refs: List[haul.types.Ref]¶
- serialized_data: Dict[str, Any]¶
- class haul.types.Ref(ids: List[haul.types.ID], field: str, nullable: bool = False, weak: bool = False)[source]¶
Bases:
object
- field: str¶
- ids: List[haul.types.ID]¶
- nullable: bool = False¶
- weak: bool = False¶
Module contents¶
- class haul.Attachment(id: str, key: Any, content_provider: Union[Callable[[], BinaryIO], NoneType] = None, _container_stream: Union[BinaryIO, NoneType] = None)[source]¶
Bases:
object
- content_provider: Optional[Callable[[], BinaryIO]] = None¶
- id: str¶
- key: Any¶
- class haul.BaseRelinkAction(fallback: Optional[haul.policy.BaseRelinkAction] = None)[source]¶
Bases:
object
Base class for new relink actions.
Override
execute()
to return a list of relinked model instances,None
or a literalFalse
to discard the object.- execute(model_cls: Type[django.db.models.base.Model], objects: List[haul.types.ObjectData], policy: haul.policy.ImportPolicy) Sequence[Optional[Union[django.db.models.base.Model, typing_extensions.Literal[False]]]] [source]¶
- fallback: Optional[haul.policy.BaseRelinkAction] = None¶
- class haul.ContainerFormat(value)[source]¶
Bases:
enum.Enum
An enumeration.
- COMPRESSED_ZIP = 2¶
- NON_COMPRESSED_ZIP = 3¶
- YAML = 1¶
- class haul.ExportContainer(exporters: List[Type[haul.serializers.Exporter]] = [], policy: Optional[haul.policy.ExportPolicy] = None, ignore_unknown=False)[source]¶
Bases:
haul.containers.base.BaseContainer
Your starting point for object export.
- export_objects(objects: Iterable[django.db.models.base.Model])[source]¶
Serializes objects and adds them to the container.
- iter_objects() Iterable[haul.types.ObjectData] [source]¶
- write(stream: IO[bytes], format: haul.types.ContainerFormat = ContainerFormat.YAML, metadata: Optional[Any] = None)[source]¶
Writes the serialized objects from the container into a data stream.
- Parameters
stream – The stream to write into. For
ContainerFormat.ZIP_*
, has to be seekable.metadata – a free-form metadata object that will be stored in the stream. It’s available later through
ImportContainer.metadata
.
- class haul.ExportPolicy[source]¶
Bases:
object
A behaviour class that defines how to handle objects during export.
- get_attachments(instance: django.db.models.base.Model) List[haul.types.Attachment] [source]¶
Override to add file or stream based attachments to an object. See
Attachment
.
- should_export_object(instance: django.db.models.base.Model)[source]¶
Override to additionally filter objects during export.
- should_follow_reference(instance: django.db.models.base.Model, target: haul.types.ID, field: str)[source]¶
Override to additionally filter FK references during export.
- class haul.Exporter(*args, **kwargs)[source]¶
Bases:
rest_framework.serializers.ModelSerializer
alias of
haul.serializers.DummyField
- class haul.ForeignKey(*args, **kwargs)[source]¶
Bases:
rest_framework.fields.Field
- bind(field_name, parent)[source]¶
Initializes the field name and parent for the field instance. Called when a field is added to the parent serializer instance.
- export_policy: haul.policy.ExportPolicy¶
- class haul.ID(kind: str, pk: Any)[source]¶
Bases:
object
- classmethod deserialize(s: Any) haul.types.ID [source]¶
- classmethod from_object(obj: django.db.models.base.Model) haul.types.ID [source]¶
- kind: str¶
- static kind_for_model(obj: Union[django.db.models.base.Model, Type[django.db.models.base.Model]])[source]¶
- pk: Any¶
- yaml_tag = 'ID'¶
- class haul.ImportContainer(exporters: List[Type[haul.serializers.Exporter]] = [], policy: Optional[haul.policy.ImportPolicy] = None, ignore_unknown=False)[source]¶
Bases:
haul.containers.base.BaseContainer
Your starting point for object import.
- import_objects() haul.containers._import.ImportReport [source]¶
Untangles the object graph, relinks objects and imports them into the database.
- metadata: Any = None¶
free-form metadata as stored by
ExportContainer.write()
- read(stream: BinaryIO)[source]¶
Reads a data stream, deserializes objects in it and stores them inside the container.
This is a context manager which has to be kept open when
import_objects()
is called:c = ImportContainer(exporters=...) with open(...) as f: with c.read(f): c.import_objects()
- class haul.ImportPolicy[source]¶
Bases:
object
A behaviour class that defines how to handle objects during import. Override its methods and pass it to
ImportContainer
to customize the behaviour.- postprocess_object_fields(model_cls: Type[django.db.models.base.Model], fields: Dict[str, Any])[source]¶
Called after
relink_object()
and before the relink actions have been applied. You can modify thefields
dict in place here.
- preprocess_object_fields(model_cls: Type[django.db.models.base.Model], fields: Dict[str, Any])[source]¶
Called after objects have been deserialized. You can modify the
fields
dict in place here.
- process_attachment(instance: django.db.models.base.Model, key: Any, stream: IO[bytes])[source]¶
Called for each attachment on a model. This is where you read and process the attachment contents. Note that the stream is not guaranteed to be open after this method exits and is guaranteed to be closed once the
ImportContainer.import()
context exits.
- process_many_to_many(instance: django.db.models.base.Model, field: str) haul.policy.ManyToManyImportAction [source]¶
Called for each M2M relation on a model. You can either return a
ManyToManyImportAction.REPLACE
orManyToManyImportAction.APPEND
here. The default isREPLACE
.
- relink_object(model_cls: Type[django.db.models.base.Model], obj: haul.types.ObjectData) haul.policy.BaseRelinkAction [source]¶
Called to decide how the imported objects should be mapped onto existing objects. This method should return an instance of a
BaseRelinkAction
subclass.The default implementation just returns
RelinkAction.Create()
- class haul.ManyToMany(*args, **kwargs)[source]¶
Bases:
haul.serializers._BaseM2X
- export_policy: haul.policy.ExportPolicy¶
- weak = False¶
- class haul.ManyToManyImportAction(value)[source]¶
Bases:
enum.Enum
An enumeration.
- APPEND = 2¶
- REPLACE = 1¶
- class haul.ObjectData(id: haul.types.ID, serialized_data: Dict[str, Any], fields: Union[Dict[str, Any], NoneType] = None, refs: List[haul.types.Ref] = <factory>, refers_to: Set[haul.types.ID] = <factory>, attachments: List[haul.types.Attachment] = <factory>)[source]¶
Bases:
object
- add_reference(ref: haul.types.Ref)[source]¶
- attachments: List[haul.types.Attachment]¶
- fields: Optional[Dict[str, Any]] = None¶
- id: haul.types.ID¶
- refers_to: Set[haul.types.ID]¶
- refs: List[haul.types.Ref]¶
- serialized_data: Dict[str, Any]¶
- class haul.Ref(ids: List[haul.types.ID], field: str, nullable: bool = False, weak: bool = False)[source]¶
Bases:
object
- field: str¶
- ids: List[haul.types.ID]¶
- nullable: bool = False¶
- weak: bool = False¶
- class haul.RelinkAction[source]¶
Bases:
object
- class Create(fallback: Optional[haul.policy.BaseRelinkAction] = None, ignore_fields: Tuple[str, ...] = <factory>)[source]¶
Bases:
haul.policy.BaseRelinkAction
A relink action that unconditionally creates new objects.
- execute(model_cls: Type[django.db.models.base.Model], objects: List[haul.types.ObjectData], policy: haul.policy.ImportPolicy) List[Union[django.db.models.base.Model, typing_extensions.Literal[False]]] [source]¶
- ignore_fields: Tuple[str, ...]¶
A list of fields to ignore during import
- class Discard(fallback: Optional[haul.policy.BaseRelinkAction] = None)[source]¶
Bases:
haul.policy.BaseRelinkAction
A relink action that unconditionally discards all objects.
- execute(_model_cls, objects: List[haul.types.ObjectData], policy: haul.policy.ImportPolicy) Sequence[Optional[Union[django.db.models.base.Model, typing_extensions.Literal[False]]]] [source]¶
- class LinkByFields(fallback: Optional[haul.policy.BaseRelinkAction] = None, overwrite_fields: Tuple[str, ...] = (), lookup_fields: Tuple[str, ...] = <factory>)[source]¶
Bases:
haul.policy.BaseRelinkActionWithFieldsOverwrite
A relink action that tries to look up existing objects by a set of fields.
- execute(model_cls: Type[django.db.models.base.Model], objects: List[haul.types.ObjectData], policy: haul.policy.ImportPolicy) Sequence[Optional[Union[django.db.models.base.Model, typing_extensions.Literal[False]]]] [source]¶
- lookup_fields: Tuple[str, ...]¶
A list of fields to use to look up existing objects
- class LinkByPK(fallback: Optional[haul.policy.BaseRelinkAction] = None, overwrite_fields: Tuple[str, ...] = ())[source]¶
Bases:
haul.policy.BaseRelinkActionWithFieldsOverwrite
A relink action that tries to map objects by their literal PK value.
This only works if the PKs are same in the source and destination databases.
- execute(model_cls: Type[django.db.models.base.Model], objects: List[haul.types.ObjectData], policy: haul.policy.ImportPolicy) List[Optional[Union[django.db.models.base.Model, typing_extensions.Literal[False]]]] [source]¶
- class LinkToInstance(fallback: Optional[haul.policy.BaseRelinkAction] = None, overwrite_fields: Tuple[str, ...] = (), pk: Optional[Hashable] = None)[source]¶
Bases:
haul.policy.BaseRelinkActionWithFieldsOverwrite
A relink action that links the object to a specific existing object.
- execute(model_cls: Type[django.db.models.base.Model], objects: List[haul.types.ObjectData], policy: haul.policy.ImportPolicy) Sequence[Union[django.db.models.base.Model, typing_extensions.Literal[False]]] [source]¶
- pk: Hashable = None¶
PK of the existing object to link to
- class LogToConsole(fallback: Optional[haul.policy.BaseRelinkAction] = None)[source]¶
Bases:
haul.policy.BaseRelinkAction
A relink action that prints the objects and links them to
None
.- execute(model_cls: Type[django.db.models.base.Model], objects: List[haul.types.ObjectData], policy: haul.policy.ImportPolicy) Sequence[Optional[Union[django.db.models.base.Model, typing_extensions.Literal[False]]]] [source]¶
- class haul.ReverseForeignKey(*args, **kwargs)[source]¶
Bases:
haul.serializers._BaseM2X
- export_policy: haul.policy.ExportPolicy¶
- weak = True¶