0

我有几个表格UUID,它们的列类型。

我想将这些列转换为,String而不是UUID因为调试很麻烦(例如,使用DB Browser for SQLite浏览sqlite文件需要我执行 SQL 查询,只是为了将对象转换为s 以查看 id 值。UUIDString

回到这个问题,最实用的方法是什么?

我正在考虑,并且即将做,但我想先问这个:

  1. 在 中registerMigration,创建一个新表。
  2. 新表现在有字符串列。
  3. 循环遍历旧表的行,并将这些行移动到新表中,但要确保 id 现在在Strings 中而不是UUIDs 中。
  4. 丢弃旧表
  5. 将新表重命名为旧表的名称。
registerMigration("UUIDMigrationToString") { db in
      try db.create(table: "new_table") { table in
        table.autoIncrementedPrimaryKey("id")
        table.column("someIdStuff", .text).notNull()
      }

      // loop through the old table...
      // move the rows from the old table to the new table but with string Ids.
      // drop old table, and rename new table.
    }
4

1 回答 1

0

GRDB作者在这里回答了这个问题:https ://github.com/groue/GRDB.swift/issues/1077

但这是我基于该答案的解决方案,应该非常简单:

import GRDB

extension DatabaseMigrator {
  /**
   Migrate UUIDs to String
   
   References:
   
   - https://github.com/groue/GRDB.swift/issues/1077
   - https://stackoverflow.com/questions/69598215/how-to-change-column-type-with-migration-with-grdb-swift
   */
  mutating func v1_8() {
    migrateStream()
  }
  
  // MARK: - Stream
  
  mutating func migrateStream() {
    registerMigration("1.8 - Stream") { db in
      
      try db.create(table: "new_stream") { table in
        table.autoIncrementedPrimaryKey("id")
        table.column("contentId", .text).notNull()
        table.column("streamId", .text).notNull()
      }
      
      let rows = try Row.fetchCursor(db, sql: "SELECT * FROM stream")
      while let row = try rows.next() {
        try db.execute(
          sql: "INSERT INTO new_stream (id, contentId, streamId) VALUES (?, ?, ?)",
          arguments: [
            row["id"],
            (row["contentId"] as UUID).uuidString,
            (row["streamId"] as UUID).uuidString
          ])
      }
      
      try db.drop(table: "stream")
      try db.rename(table: "new_stream", to: "stream")
    }
  }
于 2021-11-04T20:14:46.527 回答