Error in sanitize_metadata.py when running the multiple inputs example: None of the possible database id columns (['Accession ID', 'gisaid_epi_isl', 'genbank_accession']) were found in the metadata's columns ('strain', 'date', 'region', 'country', 'division')
**Current Behavior**

I tried to run [the multiple inputs example](https://github.com/nextstrain/ncov/blob/d08de36b5df5fba4d16d3557f93a5127397ab347/docs/src/reference/multiple_inputs.md) using `nextstrain-cli` (= Docker based), with these commands:

```
tar xf data/example_multiple_inputs.tar.xz --directory data/
nextstrain build --profile my_profiles/example_multiple_inputs
```

...and I get this during the sanitize_metadata script:

```
        python3 scripts/sanitize_metadata.py             --metadata data/example_metadata_aus.tsv             --metadata-id-columns strain name 'Virus name'             --database-id-columns 'Accession ID' gisaid_epi_isl genbank_accession             --parse-location-field Location             --rename-fields 'Virus name=strain' Type=type 'Accession ID=gisaid_epi_isl' 'Collection date=date' 'Additional location information=additional_location_information' 'Sequence length=length' Host=host 'Patient age=patient_age' Gender=sex Clade=GISAID_clade 'Pango lineage=pango_lineage' pangolin_lineage=pango_lineage Lineage=pango_lineage 'Pangolin version=pangolin_version' Variant=variant 'AA Substitutions=aa_substitutions' aaSubstitutions=aa_substitutions 'Submission date=date_submitted' 'Is reference?=is_reference' 'Is complete?=is_complete' 'Is high coverage?=is_high_coverage' 'Is low coverage?=is_low_coverage' N-Content=n_content GC-Content=gc_content             --strip-prefixes hCoV-19/ SARS-CoV-2/                          --output results/sanitized_metadata_aus.tsv.xz 2>&1 | tee logs/sanitize_metadata_aus.txt
        
ERROR: None of the possible database id columns (['Accession ID', 'gisaid_epi_isl', 'genbank_accession']) were found in the metadata's columns ('strain', 'date', 'region', 'country', 'division')
```

**Expected behavior**

Following the steps in the documentation example should work.


**How to reproduce**

Steps to reproduce the current behavior:
1. Check out commit `d08de36b5df5fba4d16d3557f93a5127397ab347`
2. Try to run the [multiple inputs example](https://github.com/nextstrain/ncov/blob/d08de36b5df5fba4d16d3557f93a5127397ab347/docs/src/reference/multiple_inputs.md)


**Possible solution**

Well, I'm completely new to this tool, but I notice that the header in the `data/example_metadata_aus.tsv` file is this:

```
strain  date    region  country division
```

...and it doesn't have any of the fields in the following command line argument to `sanitize_metadata.py`:

```
--database-id-columns 'Accession ID' gisaid_epi_isl genbank_accession
```

So either that metadata file needs to have those fields, or the example build needs to be modified not to assume these fields are in that file.


**Your environment: if running Nextstrain locally**

I'm on MacOS (Intel), and using this:

```
$ nextstrain version
nextstrain.cli 3.0.3
```

diff --git a/.travis.yml b/.travis.yml
index a09c2e74..0098aea4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,6 +11,8 @@ install:
   - nextstrain version
   - nextstrain check-setup
   - nextstrain update
+  - pip3 install cram nextstrain-augur
 script:
   - gunzip data/example_sequences.fasta.gz
   - nextstrain build . all_regions -j 2 --profile nextstrain_profiles/nextstrain-ci
+  - cram --shell=/bin/bash tests/sanitize-metadata.t
diff --git a/scripts/sanitize_metadata.py b/scripts/sanitize_metadata.py
index 40081136..dde646b4 100644
--- a/scripts/sanitize_metadata.py
+++ b/scripts/sanitize_metadata.py
@@ -168,13 +168,13 @@ def get_database_ids_by_strain(metadata_file, metadata_id_columns, database_id_c
 
     Returns
     -------
-    str or Path-like or file object :
-        Path or file object containing the mapping of database ids for each strain name (one row per combination).
+    str or Path-like or file object or None :
+        Path or file object containing the mapping of database ids for each
+        strain name (one row per combination). Returns None, if no valid
+        database ids were found and no duplicates exist.
 
     Raises
     ------
-    MissingColumnException :
-        When none of the requested database id columns exist.
     DuplicateException :
         When duplicates are detected and the caller has requested an error on duplicates.
     Exception :
@@ -189,9 +189,8 @@ def get_database_ids_by_strain(metadata_file, metadata_id_columns, database_id_c
 
     # Track strains we have observed, so we can alert the caller to duplicate
     # strains when an error on duplicates has been requested.
-    if error_on_duplicates:
-        observed_strains = set()
-        duplicate_strains = set()
+    observed_strains = set()
+    duplicate_strains = set()
 
     with NamedTemporaryFile(delete=False, mode="wt", newline='') as mapping_file:
         mapping_path = mapping_file.name
@@ -200,9 +199,16 @@ def get_database_ids_by_strain(metadata_file, metadata_id_columns, database_id_c
             valid_database_id_columns = metadata.columns.intersection(
                 database_id_columns
             )
-            if len(valid_database_id_columns) == 0:
-                raise MissingColumnException(
-                    f"None of the possible database id columns ({database_id_columns}) were found in the metadata's columns {tuple([metadata.index.name] + metadata.columns.values.tolist())}"
+            if mapping_path and len(valid_database_id_columns) == 0:
+                # Do not write out mapping of ids. Default to error on
+                # duplicates, since we have no way to resolve duplicates
+                # automatically.
+                mapping_path = None
+                error_on_duplicates = True
+                print(
+                    "WARNING: Skipping deduplication of metadata records.",
+                    f"None of the possible database id columns ({database_id_columns}) were found in the metadata's columns {tuple([metadata.index.name] + metadata.columns.values.tolist())}",
+                    file=sys.stderr
                 )
 
             # Track duplicates in memory, as needed.
@@ -213,12 +219,17 @@ def get_database_ids_by_strain(metadata_file, metadata_id_columns, database_id_c
                     else:
                         observed_strains.add(strain)
 
-            # Write mapping of database and strain ids to disk.
-            metadata.loc[:, valid_database_id_columns].to_csv(
-                mapping_file,
-                sep="\t",
-                index=True,
-            )
+            if mapping_path:
+                # Write mapping of database and strain ids to disk.
+                metadata.loc[:, valid_database_id_columns].to_csv(
+                    mapping_file,
+                    sep="\t",
+                    index=True,
+                )
+
+    # Clean up temporary file.
+    if mapping_path is None:
+        os.unlink(mapping_file.name)
 
     if error_on_duplicates and len(duplicate_strains) > 0:
         duplicates_file = metadata_file + ".duplicates.txt"
@@ -334,7 +345,7 @@ if __name__ == '__main__':
     # We will use this mapping to deduplicate records in the second pass.
     # Additionally, this pass checks for missing id columns and the presence of
     # any duplicate records, in case the user has requested an error on
-    # dupicates.
+    # duplicates.
     try:
         database_ids_by_strain = get_database_ids_by_strain(
             metadata_file,
@@ -343,7 +354,7 @@ if __name__ == '__main__':
             args.metadata_chunk_size,
             args.error_on_duplicate_strains,
         )
-    except Exception as error:
+    except (DuplicateException, Exception) as error:
         print(f"ERROR: {error}", file=sys.stderr)
         sys.exit(1)
 
@@ -363,11 +374,12 @@ if __name__ == '__main__':
 
     with open_file(args.output, "w") as output_file_handle:
         for metadata in metadata_reader:
-            # Filter duplicates.
-            metadata = filter_duplicates(
-                metadata,
-                database_ids_by_strain,
-            )
+            if database_ids_by_strain:
+                # Filter duplicates.
+                metadata = filter_duplicates(
+                    metadata,
+                    database_ids_by_strain,
+                )
 
             # Reset the data frame index, to make the "strain" column available
             # for transformation.
@@ -419,8 +431,9 @@ if __name__ == '__main__':
             )
             emit_header = False
 
-    # Delete the database/strain id mapping.
-    os.unlink(database_ids_by_strain)
+    if database_ids_by_strain:
+        # Delete the database/strain id mapping.
+        os.unlink(database_ids_by_strain)
 
     # Clean up temporary directory and files that came from a tarball.
     if metadata_is_temporary:
diff --git a/tests/sanitize-metadata.t b/tests/sanitize-metadata.t
index a45222b4..a95b87a7 100644
--- a/tests/sanitize-metadata.t
+++ b/tests/sanitize-metadata.t
@@ -44,15 +44,20 @@ Throw an error when metadata doesn't have any of the requested strain id columns
   ERROR: None of the possible id columns (['strain']) were found in the metadata's columns ('Virus name', 'gender', 'date', 'gisaid_epi_isl')
   [1]
 
-Throw an error when metadata doesn't have any of the requested database id columns.
+Print a warning when metadata doesn't have any of the requested database id columns.
+This should produce a warning about skipping duplicate resolution, an error about the duplicates found, and a file of duplicate strain names.
 
   $ python3 ../scripts/sanitize_metadata.py \
   >  --metadata unsanitized_metadata.tsv \
   >  --metadata-id-columns "Virus name" \
   >  --database-id-columns genbank_accession \
   >  --output "$TMP/metadata.tsv"
-  ERROR: None of the possible database id columns (['genbank_accession']) were found in the metadata's columns ('Virus name', 'gender', 'date', 'gisaid_epi_isl')
+  WARNING: Skipping deduplication of metadata records. None of the possible database id columns (['genbank_accession']) were found in the metadata's columns ('Virus name', 'gender', 'date', 'gisaid_epi_isl')
+  ERROR: 1 strains have duplicate records. See 'unsanitized_metadata.tsv.duplicates.txt' for more details.
   [1]
+  $ cat unsanitized_metadata.tsv.duplicates.txt
+  hCoV-19/OneVirus/1/2020
+  $ rm -f unsanitized_metadata.tsv.duplicates.txt
 
 Throw an error when metadata contain duplicates.
 
['scripts/sanitize_metadata.py', '.travis.yml', 'tests/sanitize-metadata.t']