微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何更新主键,外键指向什么,没有“ON UPDATE CASCADE”

如何解决如何更新主键,外键指向什么,没有“ON UPDATE CASCADE”

我有一个用 Django 创建的 Postgresql 数据库,里面有很多表。表之间也有多个外键。 我需要更改 users_user 表的 id(主键)字段,但是有很多表指向它。

当然理想的解决方案是向所有外键添加“ON UPDATE CASCADE”。但在我的情况下,不可能在长时间的协调过程中与其他团队就此类数据库模型更改达成协议。

因此,我需要一种无需手动指定其他表即可自动更改主键和所有外键的方法,因为有很多。

解决方法

零件:

有一种方法可以在没有中间记录的情况下在单个查询中更新主键和外键,此处描述https://stackoverflow.com/a/34383663/2622523

另外,还有一种方法可以知道,哪些表和列通过外键链接到我的表:

    SELECT
            tc.table_name,kcu.column_name      
    FROM 
        information_schema.table_constraints AS tc 
        JOIN information_schema.key_column_usage AS kcu
          ON tc.constraint_name = kcu.constraint_name
          AND tc.table_schema = kcu.table_schema
        JOIN information_schema.constraint_column_usage AS ccu
          ON ccu.constraint_name = tc.constraint_name
          AND ccu.table_schema = tc.table_schema
    WHERE tc.constraint_type = 'FOREIGN KEY' 
          and (tc.table_name='users_user' or ccu.table_name = 'users_user')

所以这两个块可以结合起来生成一个梦的 UPDATE 查询。

解决方案:

这是我遇到的一个查询:

with 
-- Source parameters
src as (
    select 
    -- Replace this with your old value,that should be changed
    '7f897d30-8261-11eb-8dcd-0242ac130003' as old_value,-- Replace this with your new value,that you need to sed
    'f243cc42-1260-4bf0-a452-8ac94b2382df' as new_value,-- Table name,which have to be used
    'users_user' as table_name,-- Column that need to be changed
    'id' as field_name
),-- here we are memorizing foreign keys,pointing to our table
forkeys as (
    SELECT
            tc.table_name,kcu.column_name      
    FROM 
        information_schema.table_constraints AS tc 
        JOIN information_schema.key_column_usage AS kcu
          ON tc.constraint_name = kcu.constraint_name
          AND tc.table_schema = kcu.table_schema
        JOIN information_schema.constraint_column_usage AS ccu
          ON ccu.constraint_name = tc.constraint_name
          AND ccu.table_schema = tc.table_schema
    WHERE tc.constraint_type = 'FOREIGN KEY' and 
          (
              tc.table_name=(select table_name from src) 
          or 
              ccu.table_name = (select table_name from src))
          ),-- constcructing 'with' part of query
withs as (
    select e'WITH ' || string_agg(q,e',') as w from (
        SELECT
            e'\nupdate_' || table_name || '_' || column_name || e' as (\n    UPDATE "' || table_name 
            || e'" SET "' || column_name || e'" = ''' || (select new_value from src) || ''' where "' 
            || column_name || e'" = ''' || (select old_value from src) || e''' returning "' 
            || column_name || e'"\n)' as q
        FROM 
            forkeys
    ) as i
),-- constucting 'main' update part of query
main as (
    select 'UPDATE "' || (select table_name from src) || '" SET "' || (select field_name from src) || '" = ''' 
        || (select new_value from src) || ''' WHERE "' || (select field_name from src) || '" = ''' || (select old_value from src) || ''''  as e

)
-- outputting
select w || e'\n' || e from main,withs

在我的例子中这个脚本的输出是:

WITH 
update_avatar_useravatar_approver_id as (
    UPDATE "avatar_useravatar" SET "approver_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "approver_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "approver_id"
),update_avatar_useravatar_user_id as (
    UPDATE "avatar_useravatar" SET "user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_id"
),update_awards_useraward_user_id as (
    UPDATE "awards_useraward" SET "user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_id"
),update_colleagues_colleagues_user_from_id as (
    UPDATE "colleagues_colleagues" SET "user_from_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_from_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_from_id"
),update_colleagues_colleagues_user_to_id as (
    UPDATE "colleagues_colleagues" SET "user_to_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_to_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_to_id"
),update_congratulations_congratulation_from_user_id as (
    UPDATE "congratulations_congratulation" SET "from_user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "from_user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "from_user_id"
),update_congratulations_congratulation_to_user_id as (
    UPDATE "congratulations_congratulation" SET "to_user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "to_user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "to_user_id"
),update_django_admin_log_user_id as (
    UPDATE "django_admin_log" SET "user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_id"
),update_following_userfollowing_from_user_id as (
    UPDATE "following_userfollowing" SET "from_user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "from_user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "from_user_id"
),update_following_userfollowing_to_user_id as (
    UPDATE "following_userfollowing" SET "to_user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "to_user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "to_user_id"
),update_keycloak_userprofilekeycloak_user_id as (
    UPDATE "keycloak_userprofilekeycloak" SET "user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_id"
),update_location_table_created_by_id as (
    UPDATE "location_table" SET "created_by_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "created_by_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "created_by_id"
),update_profile_media_profileimage_author_id as (
    UPDATE "profile_media_profileimage" SET "author_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "author_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "author_id"
),update_skills_skillapproved_user_from_id as (
    UPDATE "skills_skillapproved" SET "user_from_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_from_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_from_id"
),update_skills_skillsowners_created_by_id as (
    UPDATE "skills_skillsowners" SET "created_by_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "created_by_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "created_by_id"
),update_skills_skillsowners_owner_id as (
    UPDATE "skills_skillsowners" SET "owner_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "owner_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "owner_id"
),update_skills_usercompetence_user_id as (
    UPDATE "skills_usercompetence" SET "user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_id"
),update_structure_unit_boss_id as (
    UPDATE "structure_unit" SET "boss_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "boss_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "boss_id"
),update_structure_unit_user_id as (
    UPDATE "structure_unit" SET "user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_id"
),update_thanks_thanks_from_user_id as (
    UPDATE "thanks_thanks" SET "from_user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "from_user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "from_user_id"
),update_thanks_thanks_to_user_id as (
    UPDATE "thanks_thanks" SET "to_user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "to_user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "to_user_id"
),update_user_profile_userprofile_call_if_absent_user_id as (
    UPDATE "user_profile_userprofile_call_if_absent" SET "user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_id"
),update_user_profile_userprofile_mentor_id as (
    UPDATE "user_profile_userprofile" SET "mentor_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "mentor_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "mentor_id"
),update_user_profile_userprofile_recruiter_id as (
    UPDATE "user_profile_userprofile" SET "recruiter_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "recruiter_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "recruiter_id"
),update_user_profile_userprofile_user_id as (
    UPDATE "user_profile_userprofile" SET "user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_id"
),update_users_absence_user_id as (
    UPDATE "users_absence" SET "user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_id"
),update_users_car_user_id as (
    UPDATE "users_car" SET "user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_id"
),update_users_device_user_id as (
    UPDATE "users_device" SET "user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_id"
),update_users_education_user_id as (
    UPDATE "users_education" SET "user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_id"
),update_users_knowlanguage_user_id as (
    UPDATE "users_knowlanguage" SET "user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_id"
),update_users_user_functional_manager_id as (
    UPDATE "users_user" SET "functional_manager_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "functional_manager_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "functional_manager_id"
),update_users_user_groups_user_id as (
    UPDATE "users_user_groups" SET "user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_id"
),update_users_user_line_manager_id as (
    UPDATE "users_user" SET "line_manager_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "line_manager_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "line_manager_id"
),update_users_user_r_functional_manager_id as (
    UPDATE "users_user" SET "r_functional_manager_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "r_functional_manager_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "r_functional_manager_id"
),update_users_user_r_line_manager_id as (
    UPDATE "users_user" SET "r_line_manager_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "r_line_manager_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "r_line_manager_id"
),update_users_user_user_permissions_user_id as (
    UPDATE "users_user_user_permissions" SET "user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_id"
),update_users_usersvisibilitysettingsmodel_user_id as (
    UPDATE "users_usersvisibilitysettingsmodel" SET "user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_id"
),update_location_userplace_user_id as (
    UPDATE "location_userplace" SET "user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_id"
),update_user_extension_userextension_user_id as (
    UPDATE "user_extension_userextension" SET "user_id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' where "user_id" = '7f897d30-8261-11eb-8dcd-0242ac130003' returning "user_id"
)
UPDATE "users_user" SET "id" = 'f243cc42-1260-4bf0-a452-8ac94b2382df' WHERE "id" = '7f897d30-8261-11eb-8dcd-0242ac130003'

可以执行并应用更改。

待办事项:

  • 尚不支持复合主键/外键
  • 如果您的密钥不是 UUID,没有经过测试,可能会导致一些问题。
  • 代码是“只写”需要一些重构
  • 也许可以将代码包装到 Pl/PgSQL 代码块中,以便一次性执行。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。