A5:SQL Mk-2

開発のこと、日々のこと

FK先のテーブル名が勝手に変えられる

ホーム フォーラム A5:SQL Mk-2掲示板 FK先のテーブル名が勝手に変えられる

  • このトピックには8件の返信、1人の参加者があり、最後にabeqにより3時間、 33分前に更新されました。
9件の投稿を表示中 - 1 - 9件目 (全9件中)
  • 投稿者
    投稿
  • #31627 返信
    abeq
    ゲスト

    x64_disAIの2.21.0と2.21.1b2をwindows11上で使っています。

    sql
    CREATE TABLE “mail_member” (
    id TEXT NOT NULL REFERENCES mail(id)
    , member INTEGER NOT NULL REFERENCES member(id)
    );

    で作成したテーブルが
    sql
    CREATE TABLE “mail_member” (
    id TEXT NOT NULL REFERENCES “mails”(id)
    , member INTEGER NOT NULL REFERENCES “members”(id)
    );

    左のリスト内からテーブルをクリックしてソースタブを選択で表示された内容

    FK先のテーブル名に勝手にsが付きます。
    そんなテーブルは無いので操作でエラーが出ます。
    なぜこうなるのかを教えてください。

    #31628 返信
    abeq
    ゲスト

    sqlite3です。

    #31660 返信
    abeq
    ゲスト

    テーブルの制約やデータ型を変更する際に現テーブルを一時的に名前を変えて新テーブルを作ってデータを移行することをやっているときにFKで参照しているテーブルが名前が変わったからそれが反映された?ということでしょうか?ユーザに何のアラートも無く勝手に書き換えるのは問題ある挙動だと思います。回避する方法はあるのでしょうか?FKの制約を外せばこの挙動は無かったのでしょうか?かなり大きな不具合だと思います。

    #31669 返信
    abeq
    ゲスト

    回答を貰えないなら削除してください

    #31739 返信
    松原正和
    キーマスター

    abeq さんこんにちは。お返事が遅くなり申し訳ありません。
    (早くてもお返事は週末等になってしまいます。)
     
    テーブルのソース(CREATE TABLE)で、FK先のテーブル名が正しく表示されない件ですが、こちらで検証したのですが、再現できませんでした。
     
    後からテーブル名を変更した際に古いテーブル名で表示されるのかとも考えましたが、テーブルをリネームした後にテーブルのソースを確認すると新しいテーブル名になっていました。
     
    A5:SQL Mk-2 の仕組みとしては、
     

    select sql from sqlite_master where type=’table’ and name = ‘テーブル名’

     
    のようなSQLで、CREATE TABLE 文を取得し、整形してから表示しているのですが、こちらではどのように出力されますでしょうか?

    • この返信は1週、 2日前に松原正和が編集しました。
    • この返信は1週、 2日前に松原正和が編集しました。
    #31745 返信
    松原正和
    キーマスター

    >テーブルの制約やデータ型を変更する際に現テーブルを一時的に名前を変えて新テーブルを作ってデータを移行することをやっているときにFKで参照しているテーブルが名前が変わったからそれが反映された?ということでしょうか?

    こちら気になったので追加で調査してみたのですが、SQLite における外部キーの管理方法からの問題ではないかと思えます。

    https://stackoverflow.com/questions/4897867/update-foreign-key-references-when-doing-the-sqlite-alter-table-trick

    SQLiteは他のテーブルにあるようなシステムカタログを持たず、テーブルの情報はCREATE TABLE をテキストのまま保持します。
     
    この仕組みのため、テーブルのリネーム時は参照している外部キーを持つテーブルがないか sqlite_master テーブルを走査しリネーム対象テーブルがあればCREATE TABLE文を書き換える挙動をするようです。
     
    しかし、参照先テーブルを削除する(エラーにならない)などすると外部キーがそのまま残るなどして、問題となるケースがあるようです。

    以下例)
    1. テーブルA を作成
    2. テーブルB を作成(外部キーでテーブルAを参照)
    3. テーブルA を テーブルA´ に変更 (この時点で テーブルB の外部キーは テーブルA´ を指す)
    4. 新しく テーブルA を作成
    5. テーブルA´ を削除
    6. 最終的に テーブルB の外部キーは(存在しなくなった) テーブルA´ を指したまま残る

    #31808 返信
    abeq
    ゲスト

    松原様こんにちわ、ご回答をありがとうございます。
    SQLiteでは制約や型の変更ができないので、そうするために

    1. 現テーブルの名前を退避テーブル名に変更
    ALTER TABLE stuff RENAME TO stuffs;

    2. 制約や型などを修正したテーブルを作成
    CREATE TABLE stuff (...;

    3. 退避先からデータ移行
    INSERT INTO stuff SELECT * FROM stuffs;

    という手順を行いました。
    このテーブルを外部参照している別テーブルのフィールドの外部キー制約のテーブル名が退避テーブル名に勝手に変更されてしまいました。

    CREATE TABLE order (

    staff INTEGER NOT NULL REFERENCES stuffs(id); –←stuff(id)なのに勝手に変更
    )

    SQLiteの仕様と言われてもDB Browser for SQLiteで同操作を行っても問題はありませんでした。
    A5SQL Mk2で特にこういう実装は行っていないということであれば承知しました。

    #31863 返信
    松原正和
    キーマスター

    abeq さんこんにちは。
      
    調査したところ、SQLite 3.25.0 あたりから、テーブルをリネームすると外部キーで参照元テーブルのテーブル名を変更するようになったようです。
     
    互換性のオプションとして
     

    PRAGMA legacy_alter_table = ON;

     
    を設定(実行)することで、以前の挙動(テーブルリネームで参照元テーブル名を変更しない)になるようです。
    https://sqlite.org/pragma.html#pragma_legacy_alter_table

    #31948 返信
    abeq
    ゲスト

    松原様こんにちわ、ご教示をありがとうございます。
    こちらでもこの挙動がsqlite3の仕様であることを確認しました。
    A5:SQL側を疑って申し訳ありませんでした。
    こちらが確認した手順は古いテーブルを先にリネームするのではなく新しいテーブルを一時名で作成してデータ移行、古いテーブルをDROP、してから新しいテーブルをリネームする、ことで問題が回避できました。
    ありがとうございました。

9件の投稿を表示中 - 1 - 9件目 (全9件中)
返信先: FK先のテーブル名が勝手に変えられるで#31948に返信
あなたの情報:




コメントは受け付けていません。