device knows a lot less abot maps. It only knows it has map_names and can get mappings based on a map_name and age.
consumer does all the work of creating Extraction, running the Extraction adding a map_name to a device, creating a Map, and setting the mappings from the Extraction on the Map.
The Extraction now only transforms and extracts. It only knows what columns to extract and how to extract them. It learns how to extract from a config.
import StringAttribute.
type in new method
typo at top of file
add ExtractionColumns class for type-checking and validating columns.
Future place to store column_display_name and column_symbol_name if required.
delete extraction.py (now 'extractiontypes.py'
Map is passed a DocumentManager on init instead of freely instantiating one.

Only the application should instantiate DocumentManager, so the server/database can be easily changed.
'dbmanager' package refactored to 'models'
all app data objects to be defined here from now on
import DocumentManager from models instead of from dbmanager
add dataclasses module for classes that define behavior of data that belongs to a BaseDoc object

add Config class for job configs
change layout of device_show template so that it doesn't use tabs, use buttons at top of page instead.

still could look better