Spec-Zone.ru › DuckDB

Swift API

DuckDB предлагает Swift API. Подробности см. в статье объявления.

Инициализация DuckDB

DuckDB поддерживает как базы данных в памяти, так и постоянные базы данных. Для работы с базой данных в памяти выполните:

let database = try Database(store: .inMemory)

Для работы с постоянной базой данных выполните:

let database = try Database(store: .file(at: "test.db"))

Запросы могут выполняться через подключение к базе данных.

let connection = try database.connect()

DuckDB поддерживает несколько подключений к одной базе данных.

Пример приложения

Остальная часть страницы основана на примере из нашей статьи объявления, в котором используются исходные данные из архива экзопланет NASA, загруженные непосредственно в DuckDB.

Создание типа, специфичного для приложения

Сначала мы создаём тип, специфичный для приложения, который будет содержать нашу базу данных и соединение, и через который мы в конечном итоге определим запросы, специфичные для приложения.

import DuckDB

final class ExoplanetStore {

  let database: Database
  let connection: Connection

  init(database: Database, connection: Connection) {
    self.database = database
    self.connection = connection
  }
}

Загрузка CSV-файла

Загружаем данные из архива экзопланет NASA:

wget https://exoplanetarchive.ipac.caltech.edu/TAP/sync?query=select+pl_name+,+disc_year+from+pscomppars&format=csv -O downloaded_exoplanets.csv

После загрузки CSV-файла локально, мы можем использовать следующую SQL команду для загрузки его в качестве новой таблицы в DuckDB:

CREATE TABLE exoplanets AS
    SELECT * FROM read_csv('downloaded_exoplanets.csv');

Давайте упакуем это в новый асинхронный фабричный метод нашего ExoplanetStore типа:

import DuckDB
import Foundation

final class ExoplanetStore {

  // Factory method to create and prepare a new ExoplanetStore
  static func create() async throws -> ExoplanetStore {

  // Create our database and connection as described above
    let database = try Database(store: .inMemory)
    let connection = try database.connect()

  // Download the CSV from the exoplanet archive
  let (csvFileURL, _) = try await URLSession.shared.download(
    from: URL(string: "https://exoplanetarchive.ipac.caltech.edu/TAP/sync?query=select+pl_name+,+disc_year+from+pscomppars&format=csv")!)

  // Issue our first query to DuckDB
  try connection.execute("""
      CREATE TABLE exoplanets AS
          SELECT * FROM read_csv('\(csvFileURL.path)');
  """)

  // Create our pre-populated ExoplanetStore instance
    return ExoplanetStore(
    database: database,
      connection: connection
  )
  }

  // Let's make the initializer we defined previously
  // private. This prevents anyone accidentally instantiating
  // the store without having pre-loaded our Exoplanet CSV
  // into the database
  private init(database: Database, connection: Connection) {
  ...
  }
}

Запрос к базе данных

Следующий пример запрашивает DuckDB из Swift через асинхронную функцию. Это означает, что вызывающая сторона не будет заблокирована во время выполнения запроса. Затем мы преобразуем столбцы результатов к родным типам Swift, используя методы DuckDB ResultSet cast(to:), прежде чем, наконец, обернём их в DataFrame из фреймворка TabularData.

...

import TabularData

extension ExoplanetStore {

  // Retrieves the number of exoplanets discovered by year
  func groupedByDiscoveryYear() async throws -> DataFrame {

  // Issue the query we described above
    let result = try connection.query("""
      SELECT disc_year, count(disc_year) AS Count
        FROM exoplanets
        GROUP BY disc_year
        ORDER BY disc_year
      """)

    // Cast our DuckDB columns to their native Swift
    // equivalent types
    let discoveryYearColumn = result[0].cast(to: Int.self)
    let countColumn = result[1].cast(to: Int.self)

    // Use our DuckDB columns to instantiate TabularData
    // columns and populate a TabularData DataFrame
    return DataFrame(columns: [
      TabularData.Column(discoveryYearColumn).eraseToAnyColumn(),
      TabularData.Column(countColumn).eraseToAnyColumn(),
    ])
  }
}

Полный проект

Для полного примера проекта скопируйте репозиторий DuckDB Swift DuckDB Swift и откройте проект исполняемого приложения, расположенный по адресу Examples/SwiftUI/ExoplanetExplorer.xcodeproj.

© Copyright 2018–2024 Stichting DuckDB Foundation
Licensed under the MIT License.
https://duckdb.org/docs/api/swift.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API