たかぎとねこの忘備録

プログラミングに関する忘備録を自分用に残しときます。マサカリ怖い。

DenoDBでindex xxx already existsというエラーが出る話

db.syncを呼び出す時に、{ drop: false }オプションを指定すると次の様なエラーが出る。

SqliteError: index email already exists
      throw new SqliteError(this._wasm);

この問題はかなり報告されているぽい。

github.com

github.com

github.com

db.sync({ drop: true });を実行する場合は上述のエラーは発生しない。ただ、これではsyncが呼び出されるたびにテーブルが削除されてしまう。

自分の場合は、Userモデルのemailフィールドにuniqueを設定している場合にこのエラーがでることがわかった。

export class User extends Model {
  static table = "users";
  static timestamps = true;

  static fields = {
    id: { primaryKey: true, type: DataTypes.STRING },
    email: {
      type: DataTypes.STRING,
      unique: true,
      allowNull: false,
    },
    password: {
      type: DataTypes.STRING,
      allowNull: false,
    },
  };

  static defaults = {
    id: crypto.randomUUID(),
  };
}

uniquefalseに設定してあげる。

...
  email: {
      type: DataTypes.STRING,
      unique: false,
      allowNull: false,
  },
...

uniquefalseに設定してあげることで、db.sync({drop : false })を呼び出してもエラーが発生しないことが確認できた。

これで、アプリを起動するたびにテーブルが全部削除されることはなくなった。

しかし、データベースレベルでemailフィールドの一意性を保つことが難しくなった。なので、アプリケーションレベルで対処するように気を付ける。