Skip to content

upsert with explicit inclusion of rows instead of exclusion? #1833

@jubishop

Description

@jubishop

As far as I can tell reading the documentation for upsert, the onConflict->doUpdate closure requires you to explicitly specify which columns should not get updated by appending .noOverwrite to Columns you want to keep unchanged.

Is it possible to do the opposite and only specify the columns you want to update? I have logic where I know I specifically only want to update some columns, and itll be a bigger maintenance risk to always add a .noOverwrite for any new column I add to that table. my current raw sql solution looks like this, with some parts left out for simplicity:

let updateString =     
  rssUpdatableColumns
    .map { column, _ in
      "\(column.name) = excluded.\(column.name)"
    }
    .joined(separator: ", ")

let container = try record.databaseDictionary
let columnNames = container.keys.sorted()
let values = columnNames.map { container[$0]! }

let columnsSQL = columnNames.joined(separator: ", ")
let placeholders = columnNames.map { _ in "?" }.joined(separator: ", ")

let sql = """
  INSERT INTO \(T.databaseTableName) (\(columnsSQL))
  VALUES (\(placeholders))
  ON CONFLICT DO UPDATE SET \(updateString)
  RETURNING *
"""

this works in only updating the columns defined in rssUpdatableColumns but im wondering if theres more grdb native syntax support for this?

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions