我用
ALTER TABLE _ RENAME TO _
重命名了我的表格:
ALTER TABLE foods RENAME TO food;
ALTER TABLE foods_nutrients RENAME TO food_nutrient;
它有效,但是包含这些表名的其他数据库对象(例如索引、序列和约束)没有更新。所以我必须像这样手动更新它们:
ALTER INDEX foods_pkey RENAME TO food_pkey;
ALTER SEQUENCE foods_id_seq RENAME TO food_id_seq;
ALTER TABLE food_nutrient RENAME CONSTRAINT foods_nutrients_food_id_fkey TO food_nutrient_food_id_fkey;
没有必要重命名它们,但不这样做感觉不对。我想知道是否有命令可以自动执行此操作。或者重命名所有包含旧表名的对象并不常见?
索引、序列等名称与任何表名称之间没有技术关系。所以没有可靠的方法来自动重命名它们。
您可以编写一个脚本来遍历架构并通过搜索和替换来重命名事物,但这存在误报的风险。
这将重命名任何不遵循
$tableName_$columnName
名称的索引(复合索引将使用_
连接列组件的每个名称),$tableName_pkey
的主键索引:
-- https://stackoverflow.com/questions/1348126/postgresql-modify-owner-on-all-tables-simultaneously-in-postgresql/37259655#37259655
DO $$DECLARE r record;
BEGIN
FOR r IN
WITH pkey AS (
SELECT schema_name, table_name, constraint_name index_name, table_name || '_pkey' new_index_name
FROM (
SELECT n.nspname schema_name, cl.relname table_name, c.conname constraint_name, c.contype constraint_type
FROM pg_constraint c
JOIN pg_class cl ON c.conrelid = cl.oid
JOIN pg_namespace n ON n.oid = cl.relnamespace
) t
WHERE constraint_type = 'p'
), index AS (
SELECT schema_name, table_name, index_name, new_index_name
FROM (
SELECT schema_name, table_name, index_name, table_name || '_' || string_agg(columns, '_') new_index_name
FROM (
SELECT n.nspname schema_name, t.relname table_name, i.relname index_name, a.attname columns
FROM pg_index x
-- https://stackoverflow.com/questions/37329561/how-to-list-indexes-created-for-table-in-postgres/37330092#37330092
JOIN pg_class t ON t.oid = x.indrelid
JOIN pg_namespace n ON n.oid = t.relnamespace
JOIN pg_class i ON i.oid = x.indexrelid
-- https://stackoverflow.com/questions/55447819/how-to-get-the-list-of-column-names-for-all-indexes-on-a-table-in-postgresql/55448707#55448707
JOIN pg_attribute a ON a.attrelid = x.indrelid AND a.attnum = ANY(x.indkey)
) t
GROUP BY schema_name, table_name, index_name
) t
WHERE index_name != new_index_name
), rename AS (
SELECT index.* FROM index LEFT JOIN pkey
ON index.schema_name = pkey.schema_name
AND index.table_name = pkey.table_name
AND index.index_name != pkey.index_name
WHERE index.schema_name = 'tbm' AND pkey.schema_name = 'tbm'
UNION
SELECT * FROM pkey WHERE schema_name = 'tbm' AND index_name != new_index_name
)
SELECT 'ALTER INDEX "' || schema_name || '"."' || index_name ||
'" RENAME TO "' || new_index_name || '";' sql FROM rename
LOOP
EXECUTE r.sql;
END LOOP;
END$$;