AWS Glue examples using SDK for Swift
The following code examples show you how to perform actions and implement common scenarios by using the AWS SDK for Swift with AWS Glue.
Basics are code examples that show you how to perform the essential operations within a service.
Actions are code excerpts from larger programs and must be run in context. While actions show you how to call individual service functions, you can see actions in context in their related scenarios.
Each example includes a link to the complete source code, where you can find instructions on how to set up and run the code in context.
Basics
The following code example shows how to:
Create a crawler that crawls a public Amazon S3 bucket and generates a database of CSV-formatted metadata.
List information about databases and tables in your AWS Glue Data Catalog.
Create a job to extract CSV data from the S3 bucket, transform the data, and load JSON-formatted output into another S3 bucket.
List information about job runs, view transformed data, and clean up resources.
For more information, see Tutorial: Getting started with AWS Glue Studio.
- SDK for Swift
-
Note
There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository
. The
Package.swift
file.// swift-tools-version: 5.9 // // The swift-tools-version declares the minimum version of Swift required to // build this package. import PackageDescription let package = Package( name: "glue-scenario", // Let Xcode know the minimum Apple platforms supported. platforms: [ .macOS(.v13), .iOS(.v15) ], dependencies: [ // Dependencies declare other packages that this package depends on. .package( url: "https://github.com/awslabs/aws-sdk-swift", from: "1.0.0"), .package( url: "https://github.com/apple/swift-argument-parser.git", branch: "main" ) ], targets: [ // Targets are the basic building blocks of a package, defining a module or a test suite. // Targets can depend on other targets in this package and products // from dependencies. .executableTarget( name: "glue-scenario", dependencies: [ .product(name: "AWSGlue", package: "aws-sdk-swift"), .product(name: "AWSS3", package: "aws-sdk-swift"), .product(name: "ArgumentParser", package: "swift-argument-parser") ], path: "Sources") ] )
The Swift code file,
entry.swift
.// An example that shows how to use the AWS SDK for Swift to demonstrate // creating and using crawlers and jobs using AWS Glue. // // 0. Upload the Python job script to Amazon S3 so it can be used when // calling `startJobRun()` later. // 1. Create a crawler, pass it the IAM role and the URL of the public Amazon // S3 bucket that contains the source data: // s3://crawler-public-us-east-1/flight/2016/csv. // 2. Start the crawler. This takes time, so after starting it, use a loop // that calls `getCrawler()` until the state is "READY". // 3. Get the database created by the crawler, and the tables in the // database. Display them to the user. // 4. Create a job. Pass it the IAM role and the URL to a Python ETL script // previously uploaded to the user's S3 bucket. // 5. Start a job run, passing the following custom arguments. These are // expected by the ETL script, so must exactly match. // * `--input_database: <name of the database created by the crawler>` // * `--input_table: <name of the table created by the crawler>` // * `--output_bucket_url: <URL to the scaffold bucket created for the // user>` // 6. Loop and get the job run until it returns one of the following states: // "SUCCEEDED", "STOPPED", "FAILED", or "TIMEOUT". // 7. Output data is stored in a group of files in the user's S3 bucket. // Either direct the user to their location or download a file and display // the results inline. // 8. List the jobs for the user's account. // 9. Get job run details for a job run. // 10. Delete the demo job. // 11. Delete the database and tables created by the example. // 12. Delete the crawler created by the example. import ArgumentParser import AWSS3 import Foundation import Smithy import AWSClientRuntime import AWSGlue struct ExampleCommand: ParsableCommand { @Option(help: "The AWS IAM role to use for AWS Glue calls.") var role: String @Option(help: "The Amazon S3 bucket to use for this example.") var bucket: String @Option(help: "The Amazon S3 URL of the data to crawl.") var s3url: String = "s3://crawler-public-us-east-1/flight/2016/csv" @Option(help: "The Python script to run as a job with AWS Glue.") var script: String = "./flight_etl_job_script.py" @Option(help: "The AWS Region to run AWS API calls in.") var awsRegion = "us-east-1" @Option(help: "A prefix string to use when naming tables.") var tablePrefix = "swift-glue-basics-table" @Option( help: ArgumentHelp("The level of logging for the Swift SDK to perform."), completion: .list([ "critical", "debug", "error", "info", "notice", "trace", "warning" ]) ) var logLevel: String = "error" static var configuration = CommandConfiguration( commandName: "glue-scenario", abstract: """ Demonstrates various features of AWS Glue. """, discussion: """ An example showing how to use AWS Glue to create, run, and monitor crawlers and jobs. """ ) /// Generate and return a unique file name that begins with the specified /// string. /// /// - Parameters: /// - prefix: Text to use at the beginning of the returned name. /// /// - Returns: A string containing a unique filename that begins with the /// specified `prefix`. /// /// The returned name uses a random number between 1 million and 1 billion to /// provide reasonable certainty of uniqueness for the purposes of this /// example. func tempName(prefix: String) -> String { return "\(prefix)-\(Int.random(in: 1000000..<1000000000))" } /// Upload a file to an Amazon S3 bucket. /// /// - Parameters: /// - s3Client: The S3 client to use when uploading the file. /// - path: The local path of the source file to upload. /// - toBucket: The name of the S3 bucket into which to upload the file. /// - key: The key (name) to give the file in the S3 bucket. /// /// - Returns: `true` if the file is uploaded successfully, otherwise `false`. func uploadFile(s3Client: S3Client, path: String, toBucket: String, key: String) async -> Bool { do { let fileData: Data = try Data(contentsOf: URL(fileURLWithPath: path)) let dataStream = ByteStream.data(fileData) _ = try await s3Client.putObject( input: PutObjectInput( body: dataStream, bucket: toBucket, key: key ) ) } catch { print("*** An unexpected error occurred uploading the script to the Amazon S3 bucket \"\(bucket)\".") return false } return true } /// Create a new AWS Glue crawler. /// /// - Parameters: /// - glueClient: An AWS Glue client to use for the crawler. /// - crawlerName: A name for the new crawler. /// - iamRole: The name of an Amazon IAM role for the crawler to use. /// - s3Path: The path of an Amazon S3 folder to use as a target location. /// - cronSchedule: A `cron` schedule indicating when to run the crawler. /// - databaseName: The name of an AWS Glue database to operate on. /// /// - Returns: `true` if the crawler is created successfully, otherwise `false`. func createCrawler(glueClient: GlueClient, crawlerName: String, iamRole: String, s3Path: String, cronSchedule: String, databaseName: String) async -> Bool { let s3Target = GlueClientTypes.S3Target(path: s3url) let targetList = GlueClientTypes.CrawlerTargets(s3Targets: [s3Target]) do { _ = try await glueClient.createCrawler( input: CreateCrawlerInput( databaseName: databaseName, description: "Created by the AWS SDK for Swift Scenario Example for AWS Glue.", name: crawlerName, role: iamRole, schedule: cronSchedule, tablePrefix: tablePrefix, targets: targetList ) ) } catch _ as AlreadyExistsException { print("*** A crawler named \"\(crawlerName)\" already exists.") return false } catch _ as OperationTimeoutException { print("*** The attempt to create the AWS Glue crawler timed out.") return false } catch { print("*** An unexpected error occurred creating the AWS Glue crawler: \(error.localizedDescription)") return false } return true } /// Delete an AWS Glue crawler. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - name: The name of the crawler to delete. /// /// - Returns: `true` if successful, otherwise `false`. func deleteCrawler(glueClient: GlueClient, name: String) async -> Bool { do { _ = try await glueClient.deleteCrawler( input: DeleteCrawlerInput(name: name) ) } catch { return false } return true } /// Start running an AWS Glue crawler. /// /// - Parameters: /// - glueClient: The AWS Glue client to use when starting the crawler. /// - name: The name of the crawler to start running. /// /// - Returns: `true` if the crawler is started successfully, otherwise `false`. func startCrawler(glueClient: GlueClient, name: String) async -> Bool { do { _ = try await glueClient.startCrawler( input: StartCrawlerInput(name: name) ) } catch { print("*** An unexpected error occurred starting the crawler.") return false } return true } /// Get the state of the specified AWS Glue crawler. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - name: The name of the crawler whose state should be returned. /// /// - Returns: A `GlueClientTypes.CrawlerState` value describing the /// state of the crawler. func getCrawlerState(glueClient: GlueClient, name: String) async -> GlueClientTypes.CrawlerState { do { let output = try await glueClient.getCrawler( input: GetCrawlerInput(name: name) ) // If the crawler or its state is `nil`, report that the crawler // is stopping. This may not be what you want for your // application but it works for this one! guard let crawler = output.crawler else { return GlueClientTypes.CrawlerState.stopping } guard let state = crawler.state else { return GlueClientTypes.CrawlerState.stopping } return state } catch { return GlueClientTypes.CrawlerState.stopping } } /// Wait until the specified crawler is ready to run. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - name: The name of the crawler to wait for. /// /// - Returns: `true` if the crawler is ready, `false` if the client is /// stopping (and will therefore never be ready). func waitUntilCrawlerReady(glueClient: GlueClient, name: String) async -> Bool { while true { let state = await getCrawlerState(glueClient: glueClient, name: name) if state == .ready { return true } else if state == .stopping { return false } // Wait four seconds before trying again. do { try await Task.sleep(for: .seconds(4)) } catch { print("*** Error pausing the task.") } } } /// Create a new AWS Glue job. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - jobName: The name to give the new job. /// - role: The IAM role for the job to use when accessing AWS services. /// - scriptLocation: The AWS S3 URI of the script to be run by the job. /// /// - Returns: `true` if the job is created successfully, otherwise `false`. func createJob(glueClient: GlueClient, name jobName: String, role: String, scriptLocation: String) async -> Bool { let command = GlueClientTypes.JobCommand( name: "glueetl", pythonVersion: "3", scriptLocation: scriptLocation ) do { _ = try await glueClient.createJob( input: CreateJobInput( command: command, description: "Created by the AWS SDK for Swift Glue basic scenario example.", glueVersion: "3.0", name: jobName, numberOfWorkers: 10, role: role, workerType: .g1x ) ) } catch { return false } return true } /// Return a list of the AWS Glue jobs listed on the user's account. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - maxJobs: The maximum number of jobs to return (default: 100). /// /// - Returns: An array of strings listing the names of all available AWS /// Glue jobs. func listJobs(glueClient: GlueClient, maxJobs: Int = 100) async -> [String] { var jobList: [String] = [] var nextToken: String? repeat { do { let output = try await glueClient.listJobs( input: ListJobsInput( maxResults: maxJobs, nextToken: nextToken ) ) guard let jobs = output.jobNames else { return jobList } jobList = jobList + jobs nextToken = output.nextToken } catch { return jobList } } while (nextToken != nil) return jobList } /// Delete an AWS Glue job. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - jobName: The name of the job to delete. /// /// - Returns: `true` if the job is successfully deleted, otherwise `false`. func deleteJob(glueClient: GlueClient, name jobName: String) async -> Bool { do { _ = try await glueClient.deleteJob( input: DeleteJobInput(jobName: jobName) ) } catch { return false } return true } /// Create an AWS Glue database. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - databaseName: The name to give the new database. /// - location: The URL of the source data to use with AWS Glue. /// /// - Returns: `true` if the database is created successfully, otherwise `false`. func createDatabase(glueClient: GlueClient, name databaseName: String, location: String) async -> Bool { let databaseInput = GlueClientTypes.DatabaseInput( description: "Created by the AWS SDK for Swift Glue basic scenario example.", locationUri: location, name: databaseName ) do { _ = try await glueClient.createDatabase( input: CreateDatabaseInput( databaseInput: databaseInput ) ) } catch { return false } return true } /// Get the AWS Glue database with the specified name. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - name: The name of the database to return. /// /// - Returns: The `GlueClientTypes.Database` object describing the /// specified database, or `nil` if an error occurs or the database /// isn't found. func getDatabase(glueClient: GlueClient, name: String) async -> GlueClientTypes.Database? { do { let output = try await glueClient.getDatabase( input: GetDatabaseInput(name: name) ) return output.database } catch { return nil } } /// Returns a list of the tables in the specified database. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - databaseName: The name of the database whose tables are to be /// returned. /// /// - Returns: An array of `GlueClientTypes.Table` objects, each /// describing one table in the named database. An empty array indicates /// that there are either no tables in the database, or an error /// occurred before any tables could be found. func getTablesInDatabase(glueClient: GlueClient, databaseName: String) async -> [GlueClientTypes.Table] { var tables: [GlueClientTypes.Table] = [] var nextToken: String? repeat { do { let output = try await glueClient.getTables( input: GetTablesInput( databaseName: databaseName, nextToken: nextToken ) ) guard let tableList = output.tableList else { return tables } tables = tables + tableList nextToken = output.nextToken } catch { return tables } } while nextToken != nil return tables } /// Delete the specified database. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - databaseName: The name of the database to delete. /// - deleteTables: A Bool indicating whether or not to delete the /// tables in the database before attempting to delete the database. /// /// - Returns: `true` if the database (and optionally its tables) are /// deleted, otherwise `false`. func deleteDatabase(glueClient: GlueClient, name databaseName: String, withTables deleteTables: Bool = false) async -> Bool { if deleteTables { var tableNames: [String] = [] // Get a list of the names of all of the tables in the database. let tableList = await self.getTablesInDatabase(glueClient: glueClient, databaseName: databaseName) for table in tableList { guard let name = table.name else { continue } tableNames.append(name) } // Delete the tables. If there's only one table, use // `deleteTable()`, otherwise, use `batchDeleteTable()`. You can // use `batchDeleteTable()` for a single table, but this // demonstrates the use of `deleteTable()`. if tableNames.count == 1 { do { print(" Deleting table...") _ = try await glueClient.deleteTable( input: DeleteTableInput( databaseName: databaseName, name: tableNames[0] ) ) } catch { print("*** Unable to delete the table.") } } else { do { print(" Deleting tables...") _ = try await glueClient.batchDeleteTable( input: BatchDeleteTableInput( databaseName: databaseName, tablesToDelete: tableNames ) ) } catch { print("*** Unable to delete the tables.") } } } // Delete the database itself. do { print(" Deleting the database itself...") _ = try await glueClient.deleteDatabase( input: DeleteDatabaseInput(name: databaseName) ) } catch { print("*** Unable to delete the database.") return false } return true } /// Start an AWS Glue job run. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - jobName: The name of the job to run. /// - databaseName: The name of the AWS Glue database to run the job against. /// - tableName: The name of the table in the database to run the job against. /// - outputURL: The AWS S3 URI of the bucket location into which to /// write the resulting output. /// /// - Returns: `true` if the job run is started successfully, otherwise `false`. func startJobRun(glueClient: GlueClient, name jobName: String, databaseName: String, tableName: String, outputURL: String) async -> String? { do { let output = try await glueClient.startJobRun( input: StartJobRunInput( arguments: [ "--input_database": databaseName, "--input_table": tableName, "--output_bucket_url": outputURL ], jobName: jobName, numberOfWorkers: 10, workerType: .g1x ) ) guard let id = output.jobRunId else { return nil } return id } catch { return nil } } /// Return a list of the job runs for the specified job. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - jobName: The name of the job for which to return its job runs. /// - maxResults: The maximum number of job runs to return (default: /// 1000). /// /// - Returns: An array of `GlueClientTypes.JobRun` objects describing /// each job run. func getJobRuns(glueClient: GlueClient, name jobName: String, maxResults: Int? = nil) async -> [GlueClientTypes.JobRun] { do { let output = try await glueClient.getJobRuns( input: GetJobRunsInput( jobName: jobName, maxResults: maxResults ) ) guard let jobRuns = output.jobRuns else { print("*** No job runs found.") return [] } return jobRuns } catch is EntityNotFoundException { print("*** The specified job name, \(jobName), doesn't exist.") return [] } catch { print("*** Unexpected error getting job runs:") dump(error) return [] } } /// Get information about a specific AWS Glue job run. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - jobName: The name of the job to return job run data for. /// - id: The run ID of the specific job run to return. /// /// - Returns: A `GlueClientTypes.JobRun` object describing the state of /// the job run, or `nil` if an error occurs. func getJobRun(glueClient: GlueClient, name jobName: String, id: String) async -> GlueClientTypes.JobRun? { do { let output = try await glueClient.getJobRun( input: GetJobRunInput( jobName: jobName, runId: id ) ) return output.jobRun } catch { return nil } } /// Called by ``main()`` to run the bulk of the example. func runAsync() async throws { // A name to give the Python script upon upload to the Amazon S3 // bucket. let scriptName = "jobscript.py" // Schedule string in `cron` format, as described here: // https://docs.aws.amazon.com/glue/latest/dg/monitor-data-warehouse-schedule.html let cron = "cron(15 12 * * ? *)" let glueConfig = try await GlueClient.GlueClientConfiguration(region: awsRegion) let glueClient = GlueClient(config: glueConfig) let s3Config = try await S3Client.S3ClientConfiguration(region: awsRegion) let s3Client = S3Client(config: s3Config) // Create random names for things that need them. let crawlerName = tempName(prefix: "swift-glue-basics-crawler") let databaseName = tempName(prefix: "swift-glue-basics-db") // Create a name for the AWS Glue job. let jobName = tempName(prefix: "scenario-job") // The URL of the Python script on S3. let scriptURL = "s3://\(bucket)/\(scriptName)" print("Welcome to the AWS SDK for Swift basic scenario for AWS Glue!") //===================================================================== // 0. Upload the Python script to the target bucket so it's available // for use by the Amazon Glue service. //===================================================================== print("Uploading the Python script: \(script) as key \(scriptName)") print("Destination bucket: \(bucket)") if !(await uploadFile(s3Client: s3Client, path: script, toBucket: bucket, key: scriptName)) { return } //===================================================================== // 1. Create the database and crawler using the randomized names // generated previously. //===================================================================== print("Creating database \"\(databaseName)\"...") if !(await createDatabase(glueClient: glueClient, name: databaseName, location: s3url)) { print("*** Unable to create the database.") return } print("Creating crawler \"\(crawlerName)\"...") if !(await createCrawler(glueClient: glueClient, crawlerName: crawlerName, iamRole: role, s3Path: s3url, cronSchedule: cron, databaseName: databaseName)) { return } //===================================================================== // 2. Start the crawler, then wait for it to be ready. //===================================================================== print("Starting the crawler and waiting until it's ready...") if !(await startCrawler(glueClient: glueClient, name: crawlerName)) { _ = await deleteCrawler(glueClient: glueClient, name: crawlerName) return } if !(await waitUntilCrawlerReady(glueClient: glueClient, name: crawlerName)) { _ = await deleteCrawler(glueClient: glueClient, name: crawlerName) } //===================================================================== // 3. Get the database and table created by the crawler. //===================================================================== print("Getting the crawler's database...") let database = await getDatabase(glueClient: glueClient, name: databaseName) guard let database else { print("*** Unable to get the database.") return } print("Database URI: \(database.locationUri ?? "<unknown>")") let tableList = await getTablesInDatabase(glueClient: glueClient, databaseName: databaseName) print("Found \(tableList.count) table(s):") for table in tableList { print(" \(table.name ?? "<unnamed>")") } if tableList.count != 1 { print("*** Incorrect number of tables found. There should only be one.") _ = await deleteDatabase(glueClient: glueClient, name: databaseName, withTables: true) _ = await deleteCrawler(glueClient: glueClient, name: crawlerName) return } guard let tableName = tableList[0].name else { print("*** Table is unnamed.") _ = await deleteDatabase(glueClient: glueClient, name: databaseName, withTables: true) _ = await deleteCrawler(glueClient: glueClient, name: crawlerName) return } //===================================================================== // 4. Create a job. //===================================================================== print("Creating a job...") if !(await createJob(glueClient: glueClient, name: jobName, role: role, scriptLocation: scriptURL)) { _ = await deleteDatabase(glueClient: glueClient, name: databaseName, withTables: true) _ = await deleteCrawler(glueClient: glueClient, name: crawlerName) return } //===================================================================== // 5. Start a job run. //===================================================================== print("Starting the job...") // Construct the Amazon S3 URL for the job run's output. This is in // the bucket specified on the command line, with a folder name that's // unique for this job run. let timeStamp = Date().timeIntervalSince1970 let jobPath = "\(jobName)-\(Int(timeStamp))" let outputURL = "s3://\(bucket)/\(jobPath)" // Start the job run. let jobRunID = await startJobRun(glueClient: glueClient, name: jobName, databaseName: databaseName, tableName: tableName, outputURL: outputURL) guard let jobRunID else { print("*** Job run ID is invalid.") _ = await deleteJob(glueClient: glueClient, name: jobName) _ = await deleteDatabase(glueClient: glueClient, name: databaseName, withTables: true) _ = await deleteCrawler(glueClient: glueClient, name: crawlerName) return } //===================================================================== // 6. Wait for the job run to indicate that the run is complete. //===================================================================== print("Waiting for job run to end...") var jobRunFinished = false var jobRunState: GlueClientTypes.JobRunState repeat { let jobRun = await getJobRun(glueClient: glueClient, name: jobName, id: jobRunID) guard let jobRun else { print("*** Unable to get the job run.") _ = await deleteJob(glueClient: glueClient, name: jobName) _ = await deleteDatabase(glueClient: glueClient, name: databaseName, withTables: true) _ = await deleteCrawler(glueClient: glueClient, name: crawlerName) return } jobRunState = jobRun.jobRunState ?? .failed //===================================================================== // 7. Output where to find the data if the job run was successful. // If the job run failed for any reason, output an appropriate // error message. //===================================================================== switch jobRunState { case .succeeded: print("Job run succeeded. JSON files are in the Amazon S3 path:") print(" \(outputURL)") jobRunFinished = true case .stopped: jobRunFinished = true case .error: print("*** Error: Job run ended in an error. \(jobRun.errorMessage ?? "")") jobRunFinished = true case .failed: print("*** Error: Job run failed. \(jobRun.errorMessage ?? "")") jobRunFinished = true case .timeout: print("*** Warning: Job run timed out.") jobRunFinished = true default: do { try await Task.sleep(for: .milliseconds(250)) } catch { print("*** Error pausing the task.") } } } while jobRunFinished != true //===================================================================== // 7.5. List the job runs for this job, showing each job run's ID and // its execution time. //===================================================================== print("Getting all job runs for the job \(jobName):") let jobRuns = await getJobRuns(glueClient: glueClient, name: jobName) if jobRuns.count == 0 { print(" <no job runs found>") } else { print("Found \(jobRuns.count) job runs... listing execution times:") for jobRun in jobRuns { print(" \(jobRun.id ?? "<unnamed>"): \(jobRun.executionTime) seconds") } } //===================================================================== // 8. List the jobs for the user's account. //===================================================================== print("\nThe account has the following jobs:") let jobs = await listJobs(glueClient: glueClient) if jobs.count == 0 { print(" <no jobs found>") } else { for job in jobs { print(" \(job)") } } //===================================================================== // 9. Get the job run details for a job run. //===================================================================== print("Information about the job run:") let jobRun = await getJobRun(glueClient: glueClient, name: jobName, id: jobRunID) guard let jobRun else { print("*** Unable to retrieve the job run.") _ = await deleteJob(glueClient: glueClient, name: jobName) _ = await deleteDatabase(glueClient: glueClient, name: databaseName, withTables: true) _ = await deleteCrawler(glueClient: glueClient, name: crawlerName) return } let startDate = jobRun.startedOn ?? Date(timeIntervalSince1970: 0) let endDate = jobRun.completedOn ?? Date(timeIntervalSince1970: 0) let dateFormatter: DateFormatter = DateFormatter() dateFormatter.dateStyle = .long dateFormatter.timeStyle = .long print(" Started at: \(dateFormatter.string(from: startDate))") print(" Completed at: \(dateFormatter.string(from: endDate))") //===================================================================== // 10. Delete the job. //===================================================================== print("\nDeleting the job...") _ = await deleteJob(glueClient: glueClient, name: jobName) //===================================================================== // 11. Delete the database and tables created by this example. //===================================================================== print("Deleting the database...") _ = await deleteDatabase(glueClient: glueClient, name: databaseName, withTables: true) //===================================================================== // 12. Delete the crawler. //===================================================================== print("Deleting the crawler...") if !(await deleteCrawler(glueClient: glueClient, name: crawlerName)) { return } } } /// The program's asynchronous entry point. @main struct Main { static func main() async { let args = Array(CommandLine.arguments.dropFirst()) do { let command = try ExampleCommand.parse(args) try await command.runAsync() } catch { ExampleCommand.exit(withError: error) } } }
-
For API details, see the following topics in AWS SDK for Swift API reference.
-
Actions
The following code example shows how to use CreateCrawler
.
- SDK for Swift
-
Note
There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository
. import AWSClientRuntime import AWSGlue /// Create a new AWS Glue crawler. /// /// - Parameters: /// - glueClient: An AWS Glue client to use for the crawler. /// - crawlerName: A name for the new crawler. /// - iamRole: The name of an Amazon IAM role for the crawler to use. /// - s3Path: The path of an Amazon S3 folder to use as a target location. /// - cronSchedule: A `cron` schedule indicating when to run the crawler. /// - databaseName: The name of an AWS Glue database to operate on. /// /// - Returns: `true` if the crawler is created successfully, otherwise `false`. func createCrawler(glueClient: GlueClient, crawlerName: String, iamRole: String, s3Path: String, cronSchedule: String, databaseName: String) async -> Bool { let s3Target = GlueClientTypes.S3Target(path: s3url) let targetList = GlueClientTypes.CrawlerTargets(s3Targets: [s3Target]) do { _ = try await glueClient.createCrawler( input: CreateCrawlerInput( databaseName: databaseName, description: "Created by the AWS SDK for Swift Scenario Example for AWS Glue.", name: crawlerName, role: iamRole, schedule: cronSchedule, tablePrefix: tablePrefix, targets: targetList ) ) } catch _ as AlreadyExistsException { print("*** A crawler named \"\(crawlerName)\" already exists.") return false } catch _ as OperationTimeoutException { print("*** The attempt to create the AWS Glue crawler timed out.") return false } catch { print("*** An unexpected error occurred creating the AWS Glue crawler: \(error.localizedDescription)") return false } return true }
-
For API details, see CreateCrawler
in AWS SDK for Swift API reference.
-
The following code example shows how to use CreateJob
.
- SDK for Swift
-
Note
There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository
. import AWSClientRuntime import AWSGlue /// Create a new AWS Glue job. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - jobName: The name to give the new job. /// - role: The IAM role for the job to use when accessing AWS services. /// - scriptLocation: The AWS S3 URI of the script to be run by the job. /// /// - Returns: `true` if the job is created successfully, otherwise `false`. func createJob(glueClient: GlueClient, name jobName: String, role: String, scriptLocation: String) async -> Bool { let command = GlueClientTypes.JobCommand( name: "glueetl", pythonVersion: "3", scriptLocation: scriptLocation ) do { _ = try await glueClient.createJob( input: CreateJobInput( command: command, description: "Created by the AWS SDK for Swift Glue basic scenario example.", glueVersion: "3.0", name: jobName, numberOfWorkers: 10, role: role, workerType: .g1x ) ) } catch { return false } return true }
-
For API details, see CreateJob
in AWS SDK for Swift API reference.
-
The following code example shows how to use DeleteCrawler
.
- SDK for Swift
-
Note
There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository
. import AWSClientRuntime import AWSGlue /// Delete an AWS Glue crawler. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - name: The name of the crawler to delete. /// /// - Returns: `true` if successful, otherwise `false`. func deleteCrawler(glueClient: GlueClient, name: String) async -> Bool { do { _ = try await glueClient.deleteCrawler( input: DeleteCrawlerInput(name: name) ) } catch { return false } return true }
-
For API details, see DeleteCrawler
in AWS SDK for Swift API reference.
-
The following code example shows how to use DeleteDatabase
.
- SDK for Swift
-
Note
There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository
. import AWSClientRuntime import AWSGlue /// Delete the specified database. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - databaseName: The name of the database to delete. /// - deleteTables: A Bool indicating whether or not to delete the /// tables in the database before attempting to delete the database. /// /// - Returns: `true` if the database (and optionally its tables) are /// deleted, otherwise `false`. func deleteDatabase(glueClient: GlueClient, name databaseName: String, withTables deleteTables: Bool = false) async -> Bool { if deleteTables { var tableNames: [String] = [] // Get a list of the names of all of the tables in the database. let tableList = await self.getTablesInDatabase(glueClient: glueClient, databaseName: databaseName) for table in tableList { guard let name = table.name else { continue } tableNames.append(name) } // Delete the tables. If there's only one table, use // `deleteTable()`, otherwise, use `batchDeleteTable()`. You can // use `batchDeleteTable()` for a single table, but this // demonstrates the use of `deleteTable()`. if tableNames.count == 1 { do { print(" Deleting table...") _ = try await glueClient.deleteTable( input: DeleteTableInput( databaseName: databaseName, name: tableNames[0] ) ) } catch { print("*** Unable to delete the table.") } } else { do { print(" Deleting tables...") _ = try await glueClient.batchDeleteTable( input: BatchDeleteTableInput( databaseName: databaseName, tablesToDelete: tableNames ) ) } catch { print("*** Unable to delete the tables.") } } } // Delete the database itself. do { print(" Deleting the database itself...") _ = try await glueClient.deleteDatabase( input: DeleteDatabaseInput(name: databaseName) ) } catch { print("*** Unable to delete the database.") return false } return true }
-
For API details, see DeleteDatabase
in AWS SDK for Swift API reference.
-
The following code example shows how to use DeleteJob
.
- SDK for Swift
-
Note
There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository
. import AWSClientRuntime import AWSGlue /// Delete an AWS Glue job. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - jobName: The name of the job to delete. /// /// - Returns: `true` if the job is successfully deleted, otherwise `false`. func deleteJob(glueClient: GlueClient, name jobName: String) async -> Bool { do { _ = try await glueClient.deleteJob( input: DeleteJobInput(jobName: jobName) ) } catch { return false } return true }
-
For API details, see DeleteJob
in AWS SDK for Swift API reference.
-
The following code example shows how to use DeleteTable
.
- SDK for Swift
-
Note
There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository
. import AWSClientRuntime import AWSGlue do { print(" Deleting table...") _ = try await glueClient.deleteTable( input: DeleteTableInput( databaseName: databaseName, name: tableNames[0] ) ) } catch { print("*** Unable to delete the table.") }
-
For API details, see DeleteTable
in AWS SDK for Swift API reference.
-
The following code example shows how to use GetCrawler
.
- SDK for Swift
-
Note
There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository
. import AWSClientRuntime import AWSGlue /// Get the state of the specified AWS Glue crawler. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - name: The name of the crawler whose state should be returned. /// /// - Returns: A `GlueClientTypes.CrawlerState` value describing the /// state of the crawler. func getCrawlerState(glueClient: GlueClient, name: String) async -> GlueClientTypes.CrawlerState { do { let output = try await glueClient.getCrawler( input: GetCrawlerInput(name: name) ) // If the crawler or its state is `nil`, report that the crawler // is stopping. This may not be what you want for your // application but it works for this one! guard let crawler = output.crawler else { return GlueClientTypes.CrawlerState.stopping } guard let state = crawler.state else { return GlueClientTypes.CrawlerState.stopping } return state } catch { return GlueClientTypes.CrawlerState.stopping } }
-
For API details, see GetCrawler
in AWS SDK for Swift API reference.
-
The following code example shows how to use GetDatabase
.
- SDK for Swift
-
Note
There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository
. import AWSClientRuntime import AWSGlue /// Get the AWS Glue database with the specified name. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - name: The name of the database to return. /// /// - Returns: The `GlueClientTypes.Database` object describing the /// specified database, or `nil` if an error occurs or the database /// isn't found. func getDatabase(glueClient: GlueClient, name: String) async -> GlueClientTypes.Database? { do { let output = try await glueClient.getDatabase( input: GetDatabaseInput(name: name) ) return output.database } catch { return nil } }
-
For API details, see GetDatabase
in AWS SDK for Swift API reference.
-
The following code example shows how to use GetJobRun
.
- SDK for Swift
-
Note
There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository
. import AWSClientRuntime import AWSGlue /// Get information about a specific AWS Glue job run. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - jobName: The name of the job to return job run data for. /// - id: The run ID of the specific job run to return. /// /// - Returns: A `GlueClientTypes.JobRun` object describing the state of /// the job run, or `nil` if an error occurs. func getJobRun(glueClient: GlueClient, name jobName: String, id: String) async -> GlueClientTypes.JobRun? { do { let output = try await glueClient.getJobRun( input: GetJobRunInput( jobName: jobName, runId: id ) ) return output.jobRun } catch { return nil } }
-
For API details, see GetJobRun
in AWS SDK for Swift API reference.
-
The following code example shows how to use GetJobRuns
.
- SDK for Swift
-
Note
There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository
. import AWSClientRuntime import AWSGlue /// Return a list of the job runs for the specified job. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - jobName: The name of the job for which to return its job runs. /// - maxResults: The maximum number of job runs to return (default: /// 1000). /// /// - Returns: An array of `GlueClientTypes.JobRun` objects describing /// each job run. func getJobRuns(glueClient: GlueClient, name jobName: String, maxResults: Int? = nil) async -> [GlueClientTypes.JobRun] { do { let output = try await glueClient.getJobRuns( input: GetJobRunsInput( jobName: jobName, maxResults: maxResults ) ) guard let jobRuns = output.jobRuns else { print("*** No job runs found.") return [] } return jobRuns } catch is EntityNotFoundException { print("*** The specified job name, \(jobName), doesn't exist.") return [] } catch { print("*** Unexpected error getting job runs:") dump(error) return [] } }
-
For API details, see GetJobRuns
in AWS SDK for Swift API reference.
-
The following code example shows how to use GetTables
.
- SDK for Swift
-
Note
There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository
. import AWSClientRuntime import AWSGlue /// Returns a list of the tables in the specified database. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - databaseName: The name of the database whose tables are to be /// returned. /// /// - Returns: An array of `GlueClientTypes.Table` objects, each /// describing one table in the named database. An empty array indicates /// that there are either no tables in the database, or an error /// occurred before any tables could be found. func getTablesInDatabase(glueClient: GlueClient, databaseName: String) async -> [GlueClientTypes.Table] { var tables: [GlueClientTypes.Table] = [] var nextToken: String? repeat { do { let output = try await glueClient.getTables( input: GetTablesInput( databaseName: databaseName, nextToken: nextToken ) ) guard let tableList = output.tableList else { return tables } tables = tables + tableList nextToken = output.nextToken } catch { return tables } } while nextToken != nil return tables }
-
For API details, see GetTables
in AWS SDK for Swift API reference.
-
The following code example shows how to use ListJobs
.
- SDK for Swift
-
Note
There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository
. import AWSClientRuntime import AWSGlue /// Return a list of the AWS Glue jobs listed on the user's account. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - maxJobs: The maximum number of jobs to return (default: 100). /// /// - Returns: An array of strings listing the names of all available AWS /// Glue jobs. func listJobs(glueClient: GlueClient, maxJobs: Int = 100) async -> [String] { var jobList: [String] = [] var nextToken: String? repeat { do { let output = try await glueClient.listJobs( input: ListJobsInput( maxResults: maxJobs, nextToken: nextToken ) ) guard let jobs = output.jobNames else { return jobList } jobList = jobList + jobs nextToken = output.nextToken } catch { return jobList } } while (nextToken != nil) return jobList }
-
For API details, see ListJobs
in AWS SDK for Swift API reference.
-
The following code example shows how to use StartCrawler
.
- SDK for Swift
-
Note
There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository
. import AWSClientRuntime import AWSGlue /// Start running an AWS Glue crawler. /// /// - Parameters: /// - glueClient: The AWS Glue client to use when starting the crawler. /// - name: The name of the crawler to start running. /// /// - Returns: `true` if the crawler is started successfully, otherwise `false`. func startCrawler(glueClient: GlueClient, name: String) async -> Bool { do { _ = try await glueClient.startCrawler( input: StartCrawlerInput(name: name) ) } catch { print("*** An unexpected error occurred starting the crawler.") return false } return true }
-
For API details, see StartCrawler
in AWS SDK for Swift API reference.
-
The following code example shows how to use StartJobRun
.
- SDK for Swift
-
Note
There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository
. import AWSClientRuntime import AWSGlue /// Start an AWS Glue job run. /// /// - Parameters: /// - glueClient: The AWS Glue client to use. /// - jobName: The name of the job to run. /// - databaseName: The name of the AWS Glue database to run the job against. /// - tableName: The name of the table in the database to run the job against. /// - outputURL: The AWS S3 URI of the bucket location into which to /// write the resulting output. /// /// - Returns: `true` if the job run is started successfully, otherwise `false`. func startJobRun(glueClient: GlueClient, name jobName: String, databaseName: String, tableName: String, outputURL: String) async -> String? { do { let output = try await glueClient.startJobRun( input: StartJobRunInput( arguments: [ "--input_database": databaseName, "--input_table": tableName, "--output_bucket_url": outputURL ], jobName: jobName, numberOfWorkers: 10, workerType: .g1x ) ) guard let id = output.jobRunId else { return nil } return id } catch { return nil } }
-
For API details, see StartJobRun
in AWS SDK for Swift API reference.
-