A record with a custom primary key can be queried for in the following ways:

With the value of the primary key:

<BlockSwitcher>

<Block name="Listener (iOS 11+)">

```swift
Amplify.DataStore.query(Book.self, byIdentifier: .identifier(isbn: "12345")) { result in
    switch result {
    case .success(let book):
        guard let book = book else {
            print("Query was successful with empty result")
            return
        }
        print("Query was successful, retrieved book: \(book)")
    case .failure(let error):
        print("Error on query() for type Book with error: \(error)")
    }
}
```

</Block>

<Block name="Combine (iOS 13+)">

```swift
let sink = Amplify.DataStore.query(Book.self, byIdentifier: .identifier(isbn: "12345")).sink {
    if case let .failure(error) = $0 {
        print("Error on query() for type Book with error: \(error)")
    }
} receiveValue:{ book in
    guard let book = book else {
        print("Query was successful with empty result")
        return
    }
    print("Query was successful, retrieved book: \(book)")
}
```

</Block>

</BlockSwitcher>

With the value of QueryPredicate:

<BlockSwitcher>

<Block name="Listener (iOS 11+)">

```swift
Amplify.DataStore.query(Book.self, where: Book.keys.isbn == "12345") { result in
    switch result {
    case .success(let books):
        print("Query was successful, retrieved books: \(books)")
    case .failure(let error):
        print("Error on query() for type Book with error: \(error)")
    }
}
```

</Block>

<Block name="Combine (iOS 13+)">

```swift
let sink = Amplify.DataStore.query(Book.self, where: Book.keys.isbn == "12345").sink {
    if case let .failure(error) = $0 {
        print("Error on query() for type Book with error \(error)")
    }
} receiveValue: { books in
    print("Query was successful, retrieved books: \(books)")
}
```

</Block>

</BlockSwitcher>