Import/Export Guide
View SourceThis guide covers importing and exporting translations for bulk operations and data migration.
Overview
AshPhoenixTranslations provides comprehensive import/export functionality to help manage translations at scale. Whether you're migrating from another system, preparing translations for external translators, or performing bulk updates, the import/export tools streamline these workflows.
Export Functionality
Basic Export
Export all translations from a resource to JSON format:
mix ash_phoenix_translations.export MyApp.Product --output translations.json
Export Options
# Export specific locales
mix ash_phoenix_translations.export MyApp.Product --locales en,es,fr
# Export specific fields
mix ash_phoenix_translations.export MyApp.Product --fields name,description
# Export to CSV format
mix ash_phoenix_translations.export MyApp.Product --format csv --output translations.csv
# Include metadata
mix ash_phoenix_translations.export MyApp.Product --include-metadata
Export Formats
JSON Format
Default format, preserves full structure:
{
"products": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"translations": {
"name": {
"en": "Gaming Laptop",
"es": "Portátil Gaming",
"fr": "Ordinateur Portable Gaming"
},
"description": {
"en": "High-performance laptop",
"es": "Portátil de alto rendimiento",
"fr": "Ordinateur portable haute performance"
}
}
}
]
}CSV Format
Flat structure for spreadsheet compatibility:
id,field,locale,value
123e4567-e89b-12d3-a456-426614174000,name,en,Gaming Laptop
123e4567-e89b-12d3-a456-426614174000,name,es,Portátil Gaming
123e4567-e89b-12d3-a456-426614174000,name,fr,Ordinateur Portable GamingImport Functionality
Basic Import
Import translations from a JSON file:
mix ash_phoenix_translations.import MyApp.Product translations.json
Import Options
# Merge with existing translations
mix ash_phoenix_translations.import MyApp.Product translations.json --merge
# Replace all translations
mix ash_phoenix_translations.import MyApp.Product translations.json --replace
# Dry run to preview changes
mix ash_phoenix_translations.import MyApp.Product translations.json --dry-run
# Import from CSV
mix ash_phoenix_translations.import MyApp.Product translations.csv --format csv
Import Strategies
Merge Strategy (Default)
- Preserves existing translations
- Updates only provided translations
- Adds new translations without removing others
Replace Strategy
- Replaces all translations for affected records
- Removes translations not in import file
- Use with caution in production
Programmatic Import/Export
Export in Code
# Export all products
{:ok, json} = AshPhoenixTranslations.Export.to_json(MyApp.Product)
# Export with filters
{:ok, json} = AshPhoenixTranslations.Export.to_json(
MyApp.Product,
locales: [:en, :es],
fields: [:name, :description],
filter: [category: "electronics"]
)
# Export to CSV
{:ok, csv} = AshPhoenixTranslations.Export.to_csv(MyApp.Product)Import in Code
# Import from JSON
{:ok, results} = AshPhoenixTranslations.Import.from_json(
MyApp.Product,
json_data,
strategy: :merge
)
# Import from CSV
{:ok, results} = AshPhoenixTranslations.Import.from_csv(
MyApp.Product,
csv_data
)
# Batch import with validation
case AshPhoenixTranslations.Import.validate_and_import(MyApp.Product, data) do
{:ok, %{imported: count, errors: []}} ->
IO.puts("Successfully imported #{count} translations")
{:error, %{imported: count, errors: errors}} ->
IO.puts("Imported #{count}, failed #{length(errors)}")
Enum.each(errors, &IO.inspect/1)
endBulk Operations
Batch Translation Updates
# Update all products in a category
AshPhoenixTranslations.BulkUpdate.update_category(
"electronics",
%{
name_translations: %{
en: fn current -> "NEW: " <> current end,
es: fn current -> "NUEVO: " <> current end
}
}
)Mass Translation Validation
# Validate all translations
{:ok, report} = AshPhoenixTranslations.Validator.validate_all(MyApp.Product)
# Check completeness
missing = AshPhoenixTranslations.Validator.find_missing_translations(
MyApp.Product,
required_locales: [:en, :es, :fr]
)Migration Workflows
From Database Backend to Gettext
# 1. Export current database translations
mix ash_phoenix_translations.export MyApp.Product --output db_translations.json
# 2. Convert to Gettext format
mix ash_phoenix_translations.convert db_translations.json --to gettext
# 3. Generate .po files
mix ash_phoenix_translations.generate_po_files
From Legacy System
# Custom migration script
defmodule TranslationMigrator do
def migrate_from_legacy do
legacy_data
|> transform_to_ash_format()
|> AshPhoenixTranslations.Import.from_json(MyApp.Product)
end
defp transform_to_ash_format(legacy_data) do
# Transform legacy format to AshPhoenixTranslations format
end
endExternal Translator Workflow
Preparing Files for Translators
# Export untranslated content
mix ash_phoenix_translations.export MyApp.Product \
--missing-only \
--locales es,fr,de \
--format xlsx \
--output for_translation.xlsx
Processing Translator Returns
# Validate returned translations
mix ash_phoenix_translations.validate translated.xlsx
# Preview changes
mix ash_phoenix_translations.import MyApp.Product translated.xlsx \
--dry-run \
--show-diff
# Import validated translations
mix ash_phoenix_translations.import MyApp.Product translated.xlsx \
--backup-first
Performance Considerations
Large Dataset Exports
# Stream export for large datasets
AshPhoenixTranslations.Export.stream(MyApp.Product)
|> Stream.chunk_every(1000)
|> Stream.each(&process_chunk/1)
|> Stream.run()Chunked Imports
# Import in chunks to avoid memory issues
AshPhoenixTranslations.Import.chunked_import(
MyApp.Product,
large_dataset,
chunk_size: 500,
parallel: true
)Audit Trail
Track Import/Export Operations
# Enable audit logging
config :ash_phoenix_translations,
audit_imports: true,
audit_exports: true
# Query audit log
AshPhoenixTranslations.Audit.list_operations(
type: :import,
resource: MyApp.Product,
since: ~D[2024-01-01]
)Best Practices
Always Backup Before Import
mix ash_phoenix_translations.backup MyApp.Product mix ash_phoenix_translations.import MyApp.Product new_translations.jsonValidate Before Production Import
mix ash_phoenix_translations.import MyApp.Product translations.json --dry-runUse Appropriate Formats
- JSON for full fidelity
- CSV for translator-friendly editing
- XLSX for non-technical users
Monitor Import Performance
{:ok, stats} = AshPhoenixTranslations.Import.with_stats( MyApp.Product, data ) IO.inspect(stats.timing)
Troubleshooting
Common Issues
Large File Imports Timing Out
- Use chunked imports
- Increase timeout settings
- Process in background job
Character Encoding Issues
- Ensure UTF-8 encoding
- Use
--encoding utf8flag - Check CSV delimiter settings
Memory Issues with Large Exports
- Use streaming exports
- Export in batches
- Increase BEAM memory limits