docs: def get_field_SQL(self, field_name, field):
          """
          returns the SQL for a given field with full type information
  
          http://www.sqlite.org/datatype3.html
  
          field_name -- string -- the field's name
          field -- Field() -- the set options for the field
  
          return -- string -- the field type (eg, foo BOOL NOT NULL)
          """
          field_type = ""
          is_pk = field.options.get('pk', False)
  
          if issubclass(field.type, bool):
              field_type = 'BOOLEAN'
  
          elif issubclass(field.type, long):
              if is_pk:
                  field_type = 'INTEGER PRIMARY KEY'
              else:
                  field_type = 'BIGINT'
  
          elif issubclass(field.type, int):
              field_type = 'INTEGER'
              if is_pk:
                  field_type += ' PRIMARY KEY'
  
          elif issubclass(field.type, basestring):
              fo = field.options
              if field.is_ref():
                  # TODO -- 7-8-17 - this isn't a great way to do this, ideally the Field instance
                  # would combine all the options of both the current field and the
                  # foreign key field and return all those when Field.options is called
                  # (with the current field's options taking precedence) but there are
                  # lots of circular dependency things that happen when one field is
                  # trying to get the schema of another field and I don't have time
                  # to sort it all out right now
                  ref_s = field.schema
                  fo = ref_s.pk.options
  
              if 'size' in fo:
                  field_type = 'CHARACTER({})'.format(fo['size'])
              elif 'max_size' in fo:
                  field_type = 'VARCHAR({})'.format(fo['max_size'])
              else:
                  field_type = 'TEXT'
  
              if fo.get('ignore_case', False):
                  field_type += ' COLLATE NOCASE'
  
              if is_pk:
                  field_type += ' PRIMARY KEY'
  
          elif issubclass(field.type, datetime.datetime):
              #field_type = 'DATETIME'
              field_type = 'TIMESTAMP'
  
          elif issubclass(field.type, datetime.date):
              field_type = 'DATE'
  
          elif issubclass(field.type, float):
              field_type = 'REAL'
              size = field.options.get('size', field.options.get('max_size', 0))
              if size > 6:
                  field_type = 'DOUBLE PRECISION'
  
          elif issubclass(field.type, decimal.Decimal):
              field_type = 'NUMERIC'
  
          elif issubclass(field.type, bytearray):
              field_type = 'BLOB'
  
          else:
              raise ValueError('unknown python type: {}'.format(field.type.__name__))
  
          if field.required:
              field_type += ' NOT NULL'
          else:
              field_type += ' NULL'
  
          if not is_pk:
              if field.is_ref():
                  ref_s = field.schema
                  if field.required: # strong ref, it deletes on fk row removal
                      field_type += ' REFERENCES {} ({}) ON UPDATE CASCADE ON DELETE CASCADE'.format(
                          ref_s,
                          ref_s.pk.name
                      )
  
                  else: # weak ref, it sets column to null on fk row removal
                      field_type += ' REFERENCES {} ({}) ON UPDATE CASCADE ON DELETE SET NULL'.format(
                          ref_s,
                          ref_s.pk.name
                      )
  
          return '{} {}'.format(self._normalize_name(field_name), field_type)