Claude Code ਲਈ PostgreSQL ਮਾਈਗ੍ਰੇਸ਼ਨ ਪ੍ਰਾਂਪਟ: expand-contract ਪੈਟਰਨ, ਬੈਕਫਿਲ, ਅਤੇ ਰੋਲਬੈਕ ਯੋਜਨਾਵਾਂ ਲਈ ਸੁਰੱਖਿਅਤ ਦਿਸ਼ਾ-ਨਿਰਦੇਸ਼, ਨਾਲ ਹੀ ਰਿਲੀਜ਼ ਤੋਂ ਪਹਿਲਾਂ ਸਟੇਜਿੰਗ 'ਚ ਕੀ ਜਾਂਚਣਾ ਹੈ।

ਇੱਕ PostgreSQL ਸਕੀਮਾ ਬਦਲਾਅ ਸਧਾਰਨ ਲੱਗ ਸਕਦਾ ਹੈ ਜਦ ਤੱਕ ਉਹ ਅਸਲ ਟ੍ਰੈਫਿਕ ਅਤੇ ਅਸਲ ਡਾਟਾ ਨਾਲ ਨਹੀਂ ਮਿਲਦਾ। ਖਤਰਾ ਅਕਸਰ SQL ਖੁਦ ਨਹੀਂ ਹੁੰਦਾ; ਇਹ ਉਦੋਂ ਆਉਂਦਾ ਹੈ ਜਦੋਂ ਤੁਹਾਡੀ ਐਪ ਕੋਡ, ਡੈਟਾਬੇਸ ਦੀ ਸਥਿਤੀ, ਅਤੇ ਡਿਪਲੌਇਮੈਂਟ ਟਾਈਮਿੰਗ ਮਿਲ ਕੇ ਨਾ ਰਹਿਣ।
ਜ਼ਿਆਦਾਤਰ ਫੇਲ੍ਹਿਅਰ ਪ੍ਰਾਇਕਟਿਕ ਅਤੇ ਦਰਦਨਾਕ ਹੁੰਦੇ ਹਨ: ਇੱਕ ਡਿਪਲੌਇ ਟੁੱਟ ਜਾਂਦਾ ਹੈ ਕਿਉਂਕਿ ਓਲਡ ਕੋਡ ਨਵੀਨ ਕਾਲਮ ਨੂੰ ਰੀਫਰ ਕਰਦਾ ਹੈ, ਇੱਕ ਮਾਈਗ੍ਰੇਸ਼ਨ ਕਿਸੇ ਹੌਟ ਟੇਬਲ 'ਤੇ ਲਾਕ ਲੈ ਲੈਂਦਾ ਹੈ ਅਤੇ ਟਾਈਮਆਊਟਸ ਵਧ ਜਾਂਦੇ ਹਨ, ਜਾਂ ਇੱਕ “ਛੋਟੀ” ਬਦਲਾਵ ਚੁਪਚਾਪ ਡਾਟਾ ਨੂੰ ਡ੍ਰਾਪ ਜਾਂ ਮੁੜ ਲਿੱਖ ਦਿੰਦਾ ਹੈ। ਕਦੇ-ਕਦੇ ਕੁਝ ਨਹੀਂ ਡਿੱਗਦਾ ਪਰ ਸਬਟਲ ਬੱਗਸ਼ਿਪ ਹੁੰਦੇ ਹਨ—ਗਲਤ ਡਿਫੋਲਟ, ਟੂਟੇ ਹੋਏ ਕੰਸਟਰੇਨਟ, ਜਾਂ ਇੰਡੈਕਸ ਜੇੜਾ ਕਦੇ ਪੂਰਾ ਨਹੀਂ ਹੋਇਆ।
AI-ਜਨਰੇਟ ਕੀਤੀਆਂ ਮਾਈਗ੍ਰੇਸ਼ਨਸ ਇੱਕ ਹੋਰ ਖ਼ਤਰਾ ਜੋੜਦੀਆਂ ਹਨ। ਟੂਲ ਵੈਧ SQL ਬਣਾ ਸਕਦੇ ਹਨ ਜੋ ਤੁਹਾਡੇ ਵਰਕਲੋਡ, ਡਾਟਾ ਵਾਲਿਊਮ ਜਾਂ ਰਿਲੀਜ਼ ਪ੍ਰਕਿਰਿਆ ਲਈ ਅਸੁਰੱਖਿਅਤ ਹੋ ਸਕਦਾ ਹੈ। ਉਹ ਟੇਬਲ ਦੇ ਨਾਂ ਅਨੁਮਾਨ ਲਗਾ ਸਕਦੇ ਹਨ, ਲੰਬੇ-ਸਮੇਂ ਵਾਲੇ ਲਾਕਾਂ ਨੂੰ ਵੇਖਨਾ ਭੁੱਲ ਸਕਦੇ ਹਨ, ਜਾਂ ਡਾਊਨ ਰੋਲਬੈਕ ਨੂੰ ਹੱਲਕਾ ਲੈ ਲੈਣ—ਕਿਉਂਕਿ ਡਾਊਨ ਮਾਈਗ੍ਰੇਸ਼ਨ ਗ਼ੌਰ-ਕਠਿਨ ਹੁੰਦੇ ਹਨ। ਜੇ ਤੁਸੀਂ Claude Code ਵਰਤ ਰਹੇ ਹੋ, ਤਾਂ ਤੁਹਾਨੂੰ ਗਾਰਡਰੇਲ ਤੇ ਵਿਸ਼ੇਸ਼ ਸੰਦਰਭ ਦੀ ਲੋੜ ਹੈ।
ਇਸ ਪੋਸਟ ਵਿੱਚ ਜਦੋਂ ਅਸੀਂ ਕਹਿੰਦੇ ਹਾਂ ਕਿ ਕੋਈ ਬਦਲਾਅ “ਸੁਰੱਖਿਅਤ” ਹੈ, ਤਾਂ ਇਸਦਾ ਮਤਲਬ ਤਿੰਨ ਗੱਲਾਂ ਨਾਲ ਹੈ:
ਮਕਸਦ ਇਹ ਹੈ ਕਿ ਮਾਈਗ੍ਰੇਸ਼ਨ ਰੁਟੀਨਲ ਕੰਮ ਬਣ ਜਾਣ: ਭਵਿੱਖਵਾਣੀਯੋਗ, ਟੈਸਟਬਲ, ਅਤੇ ਬੋਰਿੰਗ।
ਕੁਝ ਨਿਗਾਹਬਾਨ ਨਿਯਮਾਂ ਨਾਲ ਸ਼ੁਰੂ ਕਰੋ। ਇਹ ਮਾਡਲ ਨੂੰ ਫੋਕਸ ਰੱਖਦੇ ਹਨ ਅਤੇ ਤੁਹਾਨੂੰ ਏਸ ਗਲਤੀ ਤੋਂ ਬਚਾਉਂਦੇ ਹਨ ਕਿ ਤੁਸੀਂ ਇੱਕ ਬਦਲਾਅ ਰਿਲੀਜ਼ ਕਰੋ ਜੋ ਸਿਰਫ ਤੁਹਾਡੇ ਲੈਪਟਾਪ 'ਤੇ ਹੀ ਚਲਦਾ ਹੋਵੇ।
ਕੰਮ ਨੂੰ ਛੋਟੇ ਕਦਮਾਂ ਵਿੱਚ ਵੰਡੋ। ਇੱਕ ਸਕੀਮਾ ਬਦਲਾਅ, ਇੱਕ ਡਾਟਾ ਬੈਕਫਿਲ, ਇੱਕ ਐਪ ਬਦਲਾਅ, ਅਤੇ ਇੱਕ ਕਲੀਨਅਪ ਕਦਮ ਵੱਖਰੇ ਖ਼ਤਰੇ ਹਨ। ਉਨ੍ਹਾਂ ਨੂੰ ਇਕੱਠਾ ਕਰਨ ਨਾਲ ਇਹ ਵੇਖਣਾ ਮੁਸ਼ਕਿਲ ਹੋ ਜਾਂਦਾ ਹੈ ਕਿ ਕੀ ਟੁੱਟਿਆ ਅਤੇ ਰੋਲਬੈਕ ਵੀ ਦੁਸ਼ਵਾਰ ਹੋ ਜਾਦਾ ਹੈ।
ਤਬਾਹੀ ਵਾਲਿਆਂ ਕੰਮਾਂ ਦੀ ਥਾਂ ਪਲੱਸਟਿਵ (ਜੋੜਨ ਵਾਲੀਆਂ) ਬਦਲਾਵਾਂ ਨੂੰ ਤਰਜੀਹ ਦਿਓ। ਕਾਲਮ, ਇੰਡੈਕਸ ਜਾਂ ਟੇਬਲ ਜੋੜਨਾ ਸਧਾਰਨ ਤੌਰ 'ਤੇ ਘੱਟ ਖਤਰਨਾਕ ਹੁੰਦਾ ਹੈ। ਆਬਜੈਕਟਾਂ ਨੂੰ ਰੀਨੇਮ ਜਾਂ ਡ੍ਰਾਪ ਕਰਨਾ ਹੀ ਅਕਸਰ ਆਊਟੇਜ ਦਾ ਕਾਰਨ ਬਣਦਾ ਹੈ। ਪਹਿਲਾਂ ਸੁਰੱਖਿਅਤ ਹਿੱਸਾ ਕਰੋ, ਐਪ ਨੂੰ ਮੂਵ ਕਰੋ, ਫਿਰ ਪੁਰਾਣੀ ਚੀਜ਼ ਨੂੰ ਸਿਰਫ ਉਸ ਵੇਲੇ ਹਟਾਓ ਜਦੋਂ ਤੁਸੀਂ ਪੱਕਾ ਹੋ ਕਿ ਉਹ ਵਰਤੀ ਨਹੀਂ ਜਾ ਰਹੀ।
ਐਪ ਨੂੰ ਕੁਝ ਸਮੇਂ ਲਈ ਦੋਹਾਂ ਸ਼ੇਪਾਂ ਨੂੰ ਸਹਿਣ ਕਰਨਾ ਸਿਖਾਓ। ਕੋਡ ਨੂੰ ਰੋਲਆਊਟ ਦੌਰਾਨ ਪੁਰਾਣੇ ਕਾਲਮ ਜਾਂ ਨਵੀਂ ਇਕੋ ਦੋਹਾਂ ਤੋਂ ਪੜ੍ਹਨ ਯੋਗ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ। ਇਸ ਨਾਲ ਆਮ ਰੇਸ ਹਾਲਤ ਤੋਂ ਬਚਾਅ ਹੁੰਦਾ ਹੈ ਜਿਸ ਵਿੱਚ ਕੁਝ ਸਰਵਰ ਨਵਾਂ ਕੋਡ ਚਲਾ ਰਹੇ ਹੁੰਦੇ ਹਨ ਜਦਕਿ ਡਾਟਾਬੇਸ ਅਜੇ ਵੀ ਪੁਰਾਣੀ ਸਥਿਤੀ 'ਤੇ ਹੁੰਦਾ ਹੈ (ਜਾਂ ਉਲਟ)।
ਮਾਈਗ੍ਰੇਸ਼ਨ ਨੂੰ ਇੱਕ ਤਿਅਾਰ ਕੋਡ ਵਾਂਗ-ਟ੍ਰੀਟ ਕਰੋ, ਨਾ ਕਿ ਇੱਕ ਜਲਦੀ ਲਿਖਿਆ ਸਕ੍ਰਿਪਟ। ਭਾਵੇਂ ਤੁਸੀਂ ਕਿਸੇ ਪਲੇਟਫਾਰਮ ਜਿਵੇਂ Koder.ai (Go ਬੈਕਐਂਡ ਨਾਲ PostgreSQL, ਅਤੇ React ਜਾਂ Flutter ਕਲਾਇਂਟ) 'ਤੇ ਕੰਮ ਕਰ ਰਹੇ ਹੋ, ਡੈਟਾਬੇਸ ਸਭ ਕੁਝ ਨਾਲ ਸਾਂਝਾ ਹੁੰਦਾ ਹੈ। ਗਲਤੀਆਂ ਮਹਿੰਗੀਆਂ ਪੈ ਸਕਦੀਆਂ ਹਨ।
ਜੇ ਤੁਸੀਂ ਹਰ SQL ਬੇਨਤੀ ਦੇ ਉਪਰ ਇੱਕ ਸੰਕੁਚਿਤ ਨਿਯਮ-ਸੈੱਟ ਚਾਹੁੰਦੇ ਹੋ, ਤਾਂ ਇਹ ਵਰਗਾ ਕੁਝ ਰੱਖੋ:
ਇੱਕ ਵਾਸਤਵਿਕ ਉਦਾਹਰਨ: ਉਸ ਦੀ ਥਾਂ ਕਿ ਤੁਸੀਂ ਇੱਕ ਕਾਲਮ ਰੀਨੇਮ ਕਰਦਿਆਂ ਜੋ ਐਪ ਤੇ ਨਿਰਭਰ ਹੈ, ਨਵਾਂ ਕਾਲਮ ਜੋੜੋ, ਹੌਲੀ-ਹੌਲੀ ਬੈਕਫਿਲ ਕਰੋ, ਐਪ ਡਿਪਲੌਇ ਕਰੋ ਜੋ ਨਵਾਂ ਫਿਰ ਪੁਰਾਣਾ ਦੇਖਦਾ ਹੈ, ਅਤੇ ਸਿਰਫ ਫਿਰ ਪੁਰਾਣਾ ਕਾਲਮ ਹਟਾਓ।
Claude ਅਸਪੱਸ਼ਟ ਬੇਨਤੀ ਤੋਂ SQL ਲਿਖ ਸਕਦਾ ਹੈ, ਪਰ ਸੁਰੱਖਿਅਤ ਮਾਈਗ੍ਰੇਸ਼ਨ ਲਈ ਸੰਦਰਭ ਲਾਜ਼ਮੀ ਹੈ। ਆਪਣੀ ਪ੍ਰਾਂਪਟ ਨੂੰ ਇੱਕ ਛੋਟੇ ਡਿਜ਼ਾਈਨ ਬ੍ਰੀਫ ਵਾਂਗ ਸਮਝੋ: ਜੋ ਮੌਜੂਦ ਹੈ ਉਹ ਦਿਖਾਓ, ਦੱਸੋ ਕਿ ਕੀ ਨਹੀਂ ਟੁੱਟਣਾ ਚਾਹੀਦਾ, ਅਤੇ ਇੱਕ ਸਫਲ ਰੋਲਆਊਟ ਲਈ "ਸੁਰੱਖਿਅਤ" ਦਾ ਮਤਲਬ ਵਿਆਖਿਆ ਕਰੋ।
শੁਰੂਆਤ ਵਿੱਚ ਕੇਵਲ ਉਹ ਡੇਟਾਬੇਸ ਤੱਥ ਪੇਸਟ ਕਰੋ ਜੋ ਮਹੱਤਵਪੂਰਨ ਹਨ। ਟੇਬਲ ਡਿਫਿਨੀਸ਼ਨ ਅਤੇ ਸੰਬੰਧਿਤ ਇੰਡੈਕਸ/ਕੰਸਟਰੇਨਟ ਸ਼ਾਮਲ ਕਰੋ (primary keys, unique constraints, foreign keys, check constraints, triggers)। ਜੇ ਸੰਬੰਧਤ ਟੇਬਲ ਹਨ, ਉਹਨਾਂ ਦੇ ਨਿਛੇ ਵੀ ਛੋਟੇ ਟੁਕੜੇ ਦਿਓ। ਇੱਕ ਛੋਟਾ, ਸਹੀ ਅੰਸ਼ ਮਾਡਲ ਨੂੰ ਅਨੁਮਾਨ ਲਾਉਣ ਤੋਂ ਬਚਾਉਂਦਾ ਹੈ।
ਅਸਲੀ ਦੁਨੀਆ ਦੀ ਸਕੇਲ ਸ਼ਾਮਲ ਕਰੋ। ਰੋਜ਼ ਕਾਊਂਟ, ਟੇਬਲ ਦਾ ਆਕਾਰ, ਲਿਖਣ ਦੀ ਰੇਟ, ਅਤੇ ਚੋਟੀ ਦਾ ਟ੍ਰੈਫਿਕ ਯੋਜਨਾ ਬਦਲ ਸਕਦੇ ਹਨ। "200M ਕਤਾਰਾਂ ਅਤੇ 1k writes/sec" ਇੱਕ ਵੱਖਰਾ ਮਾਈਗ੍ਰੇਸ਼ਨ ਹੈ ਬਨਿਸਬਤ "20k ਕਤਾਰਾਂ ਅਤੇ ਜ਼ਿਆਦਾ ਤਰ ਪੜ੍ਹਾਈ"। ਆਪਣੀ Postgres ਵਰਜਨ ਅਤੇ ਇਸ ਗੱਲ ਬਾਰੇ ਦੱਸੋ ਕਿ ਤੁਹਾਡੀ ਪ੍ਰਣਾਲੀ ਵਿੱਚ ਮਾਈਗ੍ਰੇਸ਼ਨ ਕਿਵੇਂ ਚੱਲਦੇ ਹਨ (ਸਿੰਗਲ ਟ੍ਰਾਂਜ਼ੈਕਸ਼ਨ ਵਿਰੁੱਧ ਕਈ ਕਦਮ)।
ਦੱਸੋ ਕਿ ਐਪ ਡੇਟਾ ਨੂੰ ਕਿਵੇਂ ਵਰਤਦੀ ਹੈ: ਮਹੱਤਵਪੂਰਨ ਪੜ੍ਹਾਈਆਂ, ਲਿਖਤਾਂ, ਅਤੇ ਬੈਕਗ੍ਰਾਊਂਡ ਜੌਬਸ। ਉਦਾਹਰਨ: "API reads by email", "workers update status", ਜਾਂ "reports scan by created_at". ਇਹ ਫੈਸਲਾ ਕਰਦਾ ਹੈ ਕਿ ਤੁਹਾਨੂੰ expand/contract ਦੀ ਲੋੜ ਕਿੰਨੀ ਹੈ, ਫੀਚਰ ਫਲੈਗ ਚਾਹੀਦੇ ਹਨ, ਅਤੇ ਬੈਕਫਿਲ ਕਿਤਨਾ ਸੁਰੱਖਿਅਤ ਰਹੇਗਾ।
ਆਖਿਰ ਵਿੱਚ, ਨਿਯਮ ਅਤੇ ਡਿਲਿਵਰੇਬਲ ਬਹੁਤ ਸਪਸ਼ਟ ਰੱਖੋ। ਇੱਕ ਸਧਾਰਨ ਢਾਂਚਾ ਚੰਗਾ ਕੰਮ ਕਰਦਾ ਹੈ:
ਦੋਹਾਂ SQL ਅਤੇ ਰਨ ਪਲਾਨ ਮੰਗਣ ਨਾਲ ਮਾਡਲ ਨੂੰ ਕ੍ਰਮ, ਖਤਰਾ, ਅਤੇ ਉਹ ਕੀ ਚੈੱਕ ਕਰਨਾ ਹੈ, ਇਸ ਬਾਰੇ ਸੋਚਣਾ ਪੱਢਦਾ ਹੈ।
expand/contract ਮਾਈਗ੍ਰੇਸ਼ਨ ਪੈਟਰਨ PostgreSQL ਡੈਟਾਬੇਸ ਨੂੰ ਬਦਲਣ ਦਾ ਤਰੀਕਾ ਹੈ ਬਿਨਾਂ ਐਪ ਨੁਕਸਾਨ ਪਹੁੰਚਾਏ ਜਦ ਤੱਕ ਬਦਲਾਅ ਰੋਲਆਊਟ ਹੋ ਰਿਹਾ ਹੋਵੇ। ਇਕ ਹੀ ਜੋਖਿਮ ਭਰੀ ਸਵਿੱਚ ਦੀ ਬਜਾਏ ਤੁਸੀਂ ਡੈਟਾਬੇਸ ਨੂੰ ਕੁਝ ਸਮੇਂ ਲਈ ਦੋਹਾਂ ਪੁਰਾਣੀ ਅਤੇ ਨਵੀਂ ਆਕਾਰ ਸਹਿਣਯੋਗ ਬਣਾਉਂਦੇ ਹੋ।
ਇਸਨੂੰ ਸੋਚੋ: ਪਹਿਲਾਂ ਨਵੀਆਂ ਚੀਜ਼ਾਂ ਸੁਰੱਖਿਅਤ ਤਰੀਕੇ ਨਾਲ ਜੋੜੋ (expand), ਫਿਰ ਟ੍ਰੈਫਿਕ ਅਤੇ ਡੇਟਾ ਹੌਲੀ-ਹੌਲੀ ਮੂਵ ਕਰੋ, ਅਤੇ ਅੰਤੀਮ ਤੌਰ 'ਤੇ ਪੁਰਾਣੀਆਂ ਚੀਜ਼ਾਂ ਹਟਾਓ (contract)। ਇਹ ਖਾਸ ਤੌਰ 'ਤੇ AI-ਸਹਾਇਤ ਕੰਮ ਲਈ ਲਾਭਦਾਇਕ ਹੈ ਕਿਉਂਕਿ ਇਹ ਤੁਹਾਨੂੰ ਮੈਸੀ ਦੌਰ ਲਈ ਯੋਜਨਾ ਬਣਾਉਣ 'ਤੇ ਮਜਬੂਰ ਕਰਦਾ ਹੈ।
ਇੱਕ ਪ੍ਰਾਇਕਟਿਕ ਫਲੋ ਇਉਂ ਦਿੱਖਦਾ ਹੈ:
ਜਦੋਂ ਵੀ ਯੂਜ਼ਰ ਅਜੇ ਵੀ ਪੁਰਾਣੀ ਐਪ ਕੋਡ 'ਤੇ ਹੋ ਸਕਦੇ ਹਨ ਜਾਂ ਡਾਟਾਬੇਸ ਬਦਲ ਰਿਹਾ ਹੋਵੇ ਤਾਂ ਇਸ ਪੈਟਰਨ ਦੀ ਵਰਤੋਂ ਕਰੋ। ਇਸ ਵਿੱਚ multi-instance deployments, ਮੋਬਾਈਲ ਐਪ ਜੋ ਹੌਲੇ-ਹੌਲੇ ਅਪਡੇਟ ਹੁੰਦੇ ਹਨ, ਜਾਂ ਕੋਈ ਵੀ ਰਿਲੀਜ਼ ਜਿੱਥੇ ਮਾਈਗ੍ਰੇਸ਼ਨ ਕੁਝ ਮਿੰਟਾਂ ਜਾਂ ਘੰਟਿਆਂ ਤੱਕ ਲੱਗ ਸਕਦੀ ਹੈ, ਸ਼ਾਮਲ ਹਨ।
ਇੱਕ ਮਦਦਗਾਰ ਤਕੰਨੀਕ ਦੋ ਰਿਲੀਜ਼ਾਂ ਦੀ ਯੋਜਨਾ ਬਣਾਉਣਾ ਹੈ। ਰਿਲੀਜ਼ 1 ਵਿੱਚ expand + compatibility ਕਰੋ ਤਾਂ ਕਿ ਬੈਕਫਿਲ ਅਧੂਰਾ ਹੋਣ 'ਤੇ ਵੀ ਕੁਝ ਟੁਟੇ ਨਾ। ਰਿਲੀਜ਼ 2 ਵਿੱਚ ਸਿਰਫ contract ਕਰੋ ਜਦੋਂ ਤੁਸੀਂ ਨਵੇਂ ਕੋਡ ਅਤੇ ਨਵੇਂ ਡੇਟਾ ਦੀ ਪੁਸ਼ਟੀ ਕਰ ਲਓ।
ਇਸ ਟੈਮਪਲੇਟ ਨੂੰ ਕਾਪੀ ਕਰੋ ਅਤੇ ਬ੍ਰੈਕਟ ਵਿੱਚ ਭਰੋ। ਇਹ Claude Code ਨੂੰ SQL ਦੇਣ, ਚੈੱਕਸ ਦਿਖਾਉਣ, ਅਤੇ ਇੱਕ ਅਮਲਯੋਗ ਰੋਲਬੈਕ ਯੋਜਨਾ ਦੇਣ ਲਈ ਧੱਕੇ ਦਿੰਦਾ ਹੈ।
You are helping me plan a PostgreSQL expand-contract migration.
Context
- App: [what the feature does, who uses it]
- Database: PostgreSQL [version if known]
- Table sizes: [rough row counts], write rate: [low/medium/high]
- Zero/near-zero downtime required: [yes/no]
Goal
- Change: [describe the schema change]
- Current schema (relevant parts):
[paste CREATE TABLE or \d output]
- How the app will change (expand phase and contract phase):
- Expand: [new columns/indexes/triggers, dual-write, read preference]
- Contract: [when/how we stop writing old fields and remove them]
Hard safety requirements
- Prefer lock-safe operations. Avoid full table rewrites on large tables when possible.
- If any step can block writes, call it out explicitly and suggest alternatives.
- Use small, reversible steps. No “big bang” changes.
Deliverables
1) UP migration SQL (expand)
- Use clear comments.
- If you propose indexes, tell me if they should be created CONCURRENTLY.
- If you propose constraints, tell me whether to add them NOT VALID then VALIDATE.
2) Verification queries
- Queries to confirm the new schema exists.
- Queries to confirm data is being written to both old and new structures (if dual-write).
- Queries to estimate whether the change caused bloat/slow queries/locks.
3) Rollback plan (realistic)
- DOWN migration SQL (only if it is truly safe).
- If down is not safe, write a rollback runbook:
- how to stop the app change
- how to switch reads back
- what data might be lost or need re-backfill
4) Runbook notes
- Exact order of operations (including app deploy steps).
- What to monitor during the run (errors, latency, deadlocks, lock waits).
- “Stop/continue” checkpoints.
Output format
- Separate sections titled: UP.sql, VERIFY.sql, DOWN.sql (or ROLLBACK.md), RUNBOOK.md
ਦੋ ਐਕਸਟਰਾ ਲਾਈਨਾਂ ਜੋ ਅਮਲ ਵਿੱਚ ਮਦਦਗਾਰ ਹਨ:
RISK: blocks writes ਲੇਬਲ ਕਰਨ ਲਈ ਕਹੋ, ਨਾਲ ਹੀ ਕਦੋਂ ਚਲਾਉਣਾ ਹੈ (off-peak vs anytime).ਛੋਟੇ ਸਕੀਮਾ ਬਦਲਾਅ ਵੀ ਨੁਕਸਾਨ ਕਰ ਸਕਦੇ ਹਨ ਜੇ ਉਹ ਲੰਬੇ ਲਾਕ ਲੈਂ, ਵੱਡੇ ਟੇਬਲ ਨੂੰ ਦੁਬਾਰਾ ਲਿਖਦੇ ਹਨ, ਜਾਂ ਅੱਧੇ ਰਾਹ 'ਤੇ ਫੇਲ੍ਹ ਹੋ ਜਾਂਦੇ ਹਨ। ਜਦੋਂ ਤੁਸੀਂ Claude Code ਨਾਲ ਮਾਈਗ੍ਰੇਸ਼ਨ ਕਰਦੇ ਹੋ, ਤਾਂ ਉਹਨਾਂ ਤੋਂ ਪੂਛੋ ਕਿ SQL ਰੀ-ਰਾਈਟ ਤੋਂ ਬਚੇ ਅਤੇ ਡੈਟਾਬੇਸ ਜਾਂਚ ਦੌਰਾਨ ਕੰਮ ਕਰਦਾ ਰਹੇ।
nullable ਕਾਲਮ ਜੋੜਨਾ ਆਮ ਤੌਰ 'ਤੇ ਸੁਰੱਖਿਅਤ ਹੁੰਦਾ ਹੈ। non-null ਡਿਫੋਲਟ ਵਾਲੇ ਕਾਲਮ ਨੂੰ ਜੋੜਨਾ ਕੁਝ ਪੁਰਾਣੀਆਂ Postgres ਵਰਜਨਾਂ 'ਤੇ ਟੇਬਲ ਨੂੰ ਮੁੜ ਲਿਖ ਸਕਦਾ ਹੈ ਅਤੇ ਖਤਰਨਾਕ ਹੋ ਸਕਦਾ ਹੈ।
ਇੱਕ ਸੁਰੱਖਿਅਤ ਤਰੀਕਾ ਦੋ ਕਦਮ ਦਾ ਹੁੰਦਾ ਹੈ: ਕਾਲਮ ਨੂੰ NULL ਨਾਲ ਜੋੜੋ ਬਿਨਾਂ ਡਿਫੋਲਟ ਦੇ, ਬੈਕਫਿਲ ਛੋਟੇ-ਛੋਟੇ ਬੈਚਾਂ 'ਚ ਕਰੋ, ਫਿਰ ਨਵੀਆਂ ਲਾਈਨਾਂ ਲਈ ਡਿਫੋਲਟ ਸੈੱਟ ਕਰੋ ਅਤੇ ਡੇਟਾ ਸਾਫ ਹੋਣ 'ਤੇ NOT NULL ਜੋੜੋ।
ਜੇ ਤੁਹਾਨੂੰ ਤੁਰੰਤ ਡਿਫੋਲਟ ਲਾਜ਼ਮੀ ਹੈ, ਤਾਂ ਆਪਣੇ Postgres ਵਰਜਨ ਲਈ ਲਾਕ ਵਿਹਾਰ ਬਾਰੇ ਵਿਆਖਿਆ ਮੰਗੋ ਅਤੇ ਜੇ ਚਲਣ ਸਮੇਂ ਲੰਮਾ ਹੋ ਜਾਵੇ ਤਾਂ ਇੱਕ ਫੌਲਬੈਕ ਯੋਜਨਾ ਦਿਓ।
ਵੱਡੇ ਟੇਬਲਾਂ 'ਤੇ ਇੰਡੈਕਸ ਲਈ, CREATE INDEX CONCURRENTLY ਮੰਗੋ ਤਾਂ ਕਿ ਪੜ੍ਹਾਈਆਂ ਅਤੇ ਲਿਖਤਾਂ ਜਾਰੀ ਰਹਿਣ। ਇਹ ਨੋਟ ਵੀ ਕਰਵਾਓ ਕਿ ਇਹ ਟ੍ਰਾਂਜ਼ੈਕਸ਼ਨ ਬਲਾਕ ਵਿਚ ਨਹੀਂ ਚੱਲ ਸਕਦਾ, ਜਿਸਦਾ ਮਤਲਬ ਹੈ ਕਿ ਤੁਹਾਡੇ ਮਾਈਗ੍ਰੇਸ਼ਨ ਟੂਲ ਨੂੰ ਗੈਰ-ਟ੍ਰਾਂਜ਼ੈਕਸ਼ਨਲ ਕਦਮ ਦਾ ਸਮਰਥਨ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ।
ਫਾਰਨ ਕੀਜ਼ ਲਈ, ਆਮ ਤੌਰ 'ਤੇ ਕੰਸਟਰੇਨਟ ਨੂੰ ਪਹਿਲਾਂ NOT VALID ਵਜੋਂ ਜੋੜਨਾ ਸੁਰੱਖਿਅਤ ਰਾਹ ਹੁੰਦਾ ਹੈ, ਫਿਰ ਬਾਅਦ ਵਿੱਚ ਵੈਲਿਡੇਟ ਕਰਨਾ। ਇਹ ਪ੍ਰਾਥਮਿਕ ਬਦਲਾਵ ਨੂੰ ਤੇਜ਼ ਰੱਖਦਾ ਹੈ ਪਰ ਨਵੇਂ ਲਿਖਤਾਂ ਲਈ FK ਲਾਗੂ ਕਰਦਾ ਹੈ।
ਜਦੋਂ ਤੁਸੀਂ ਕੰਸਟਰੇਨਟ ਜ਼ਿਆਦਾ ਕਠੋਰ ਕਰ ਰਹੇ ਹੋ (NOT NULL, UNIQUE, CHECK), ਤਾਂ "ਸਾਫ਼ ਕਰੋ ਪਹਿਲਾਂ, ਫਿਰ ਲਾਗੂ ਕਰੋ" ਪਾਲੋ। ਮਾਈਗ੍ਰੇਸ਼ਨ ਖਰਾਬ ਰੋਜ਼ਾਂ ਦੀ ਪਹਚਾਨ ਕਰਕੇ ਉਹਨਾਂ ਨੂੰ ਠੀਕ ਕਰੇ ਅਤੇ ਫਿਰ ਸਖਤੀ ਅਨੁਮੋਡੇ।
ਜੇ ਤੁਸੀਂ ਇੱਕ ਛੋਟੀ ਚੈੱਕਲਿਸਟ ਚਾਹੁੰਦੇ ਹੋ ਪ੍ਰਾਂਪਟ ਵਿੱਚ ਚਿਪਕਾਉਣ ਲਈ, ਇਨ੍ਹਾਂ ਨੂੰ ਛੋਟਾ ਰੱਖੋ:
ਬੈਕਫਿਲ ਉਹ ਜਗ੍ਹਾ ਹੈ ਜਿਥੇ ਵੱਧ ਤੱਕ ਦਰਦ ਹੁੰਦਾ ਹੈ, ਨਾ ਕਿ ALTER TABLE। ਸੁਰੱਖਿਅਤ ਪ੍ਰਾਂਪਟ ਉਹਨਾਂ ਨੂੰ ਕੰਟਰੋਲਡ ਜੌਬਸ ਵਾਂਗ ਮੰਗਦਾ ਹੈ: ਮਾਪਣਯੋਗ, ਰੀਜ਼ਿਊਮਯੋਗ, ਅਤੇ ਪ੍ਰੋਡਕਸ਼ਨ 'ਤੇ ਹੌਲੇ।
ਸ਼ੁਰੂ ਵਿੱਚ ਸਵੀਕਾਰੋ: ਉਮੀਦ ਕੀਤੀ ਰੋਜ਼ ਗਿਣਤੀ, ਹدف ਨੱਲ ਰੇਟ, ਅਤੇ ਕੁਝ ਸਪਾਟ ਚੈੱਕਸ (ਉਦਾਹਰਨ ਲਈ 20 ਰੈਂਡਮ IDs ਲਈ ਨਵਾਂ ਬਿਲਕੁਲ ਪੁਰਾਣਾ ਮੁਕਾਬਲਾ) ਕਠੋਰ ਚੈੱਕ ਹੋਣੇ ਚਾਹੀਦੇ ਹਨ।
ਫਿਰ ਇੱਕ ਬੈਚਿੰਗ ਯੋਜਨਾ ਮੰਗੋ। ਬੈਚ ਲਾਕ ਛੋਟੇ ਰੱਖਦੇ ਹਨ ਅਤੇ ਅਣਚਾਹੇ ਨਤੀਜਿਆਂ ਨੂੰ ਘਟਾਉਂਦੇ ਹਨ। ਇੱਕ ਚੰਗੀ ਬੇਨਤੀ ਵਿੱਚ ਦਰਸਾਇਆ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ:
ਆਈਡੈਮਪੋਟੈਂਸੀ ਲਾਜ਼ਮੀ ਕਰੋ ਕਿਉਂਕਿ ਬੈਕਫਿਲ ਅੱਧੇ-ਰਾਹ ਫੇਲ੍ਹ ਹੁੰਦੇ ਹਨ। SQL ਨੂੰ ਦੁਬਾਰਾ ਚਲਾਉਣ ਯੋਗ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ ਬਿਨਾਂ ਡੁਪਲੀਕੇਟ ਜਾਂ ਡੇਟਾ ਨੁਕਸਾਨ ਦੇ। ਆਮ ਪੈਟਰਨ ਹਨ "ਸਿਰਫ਼ ਜਿੱਥੇ new_column IS NULL ਅਪਡੇਟ ਕਰੋ" ਜਾਂ ਇੱਕ ਨਿਰਧਾਰਿਤ ਨਿਯਮ ਜਿਸ ਵਿੱਚ ਇੱਕੋ ਇਨਪੁਟ ਹਮੇਸ਼ਾ ਇੱਕੋ ਨਤੀਜਾ ਦਿੰਦਾ ਹੈ।
ਐਪ ਬੈਕਫਿਲ ਦੌਰਾਨ ਸਹੀ ਰਹੇ ਕਿਵੇਂ ਇਹ ਵੀ ਸਪਸ਼ਟ ਕਰੋ। ਜੇ ਨਵੀਆਂ ਲਿਖਤਾਂ ਆ ਰਹੀਆਂ ਹਨ, ਤੁਹਾਨੂੰ ਇੱਕ ਪُل ਚਾਹੀਦਾ ਹੈ: ਐਪ ਕੋਡ ਵਿੱਚ dual-write, ਅਸਥਾਈ ਟ੍ਰਿਗਰ, ਜਾਂ read-fallback ਲਾਜ਼ਮੀ। ਕਹੋ ਕਿ ਤੁਸੀਂ ਕਿਹੜਾ ਤਰੀਕਾ ਸੁਰੱਖਿਅਤ ਤਰੀਕੇ ਨਾਲ ਡਿਪਲੌਇ ਕਰ ਸਕਦੇ ਹੋ।
ਆਖਿਰ ਵਿੱਚ, ਡਿਜ਼ਾਈਨ ਵਿੱਚ ਰੋਕਣ ਅਤੇ ਰੀਜ਼ਿਊਮ ਸਮਰਥਨ ਬਣਾੋ। ਪ੍ਰਗਟੀ ਦੀ ਰਿਪੋਰਟਿੰਗ ਅਤੇ ਚੈੱਕਪੋਇੰਟਸ ਜਿਵੇਂ ਇੱਕ ਛੋਟੀ ਟੇਬਲ ਜੋ ਅੰਤਿਮ ਪ੍ਰੋਸੈਸ ਕੀਤੇ ID ਨੂੰ ਰੱਖਦੀ ਹੈ ਅਤੇ ਇੱਕ ਕੈਵਰੀ ਜੋ ਪ੍ਰਗਟੀ (rows updated, last ID, time started) ਦਿਖਾਉਂਦੀ ਹੈ।
ਉਦਾਹਰਨ: ਤੁਸੀਂ users.full_name ਜੋ first_name ਅਤੇ last_name ਤੋਂ ਬਣਦਾ ਹੈ ਜੋੜਦੇ ਹੋ। ਇੱਕ ਸੁਰੱਖਿਅਤ ਬੈਕਫਿਲ ਸਿਰਫ ਉਸੇ ਰੋਜ਼ਾਂ ਨੂੰ ਅਪਡੇਟ ਕਰੇਗਾ ਜਿੱਥੇ full_name IS NULL, ID ਰੇਂਜਾਂ ਵਿੱਚ ਚੱਲੇਗਾ, ਅੰਤਿਮ ਅੱਪਡੇਟ ID ਰਿਕਾਰਡ ਕਰੇਗਾ, ਅਤੇ ਨਵੀਂ ਸਾਇਨਅੱਪਸ ਦੌਰਾਨ dual-write ਰਾਹੀਂ ਸਹੀ ਰਿਹਾ ਜਾਵੇਗਾ।
ਰੋਲਬੈਕ ਯੋਜਨਾ ਸਿਰਫ "ਡਾਊਨ ਮਾਈਗ੍ਰੇਸ਼ਨ ਲਿਖੋ" ਨਹੀਂ ਹੁੰਦੀ। ਇਹ ਦੋ ਸਮੱਸਿਆਵਾਂ ਹਨ: ਸਕੀਮਾ ਬਦਲਾਉਂ ਨੂੰ ਵਾਪਸ ਲੈਣਾ ਅਤੇ ਉਹ ਡੇਟਾ ਜੋ ਨਵੇਂ ਵਰਜਨ ਦੌਰਾਨ ਬਦਲਾ ਉਹਨੂੰ ਸੰਭਾਲਣਾ। ਸਕੀਮਾ ਰੋਲਬੈਕ ਅਕਸਰ ਸੰਭਵ ਹੁੰਦਾ ਹੈ। ਡੇਟਾ ਰੋਲਬੈਕ ਆਮ ਤੌਰ 'ਤੇ ਸੰਭਵ ਨਹੀਂ ਹੁੰਦਾ ਜਦ ਤੱਕ ਤੁਸੀਂ ਪਹਿਲਾਂ ਤੋਂ ਯੋਜਨਾ ਨਹੀਂ ਬਣਾਈ।
ਰੋਲਬੈਕ ਦਾ ਕੀ ਮਤਲਬ ਹੈ ਇਸ 'ਤੇ ਸਪਸ਼ਟ ਹੋਵੋ। ਜੇ ਤੁਸੀਂ ਇੱਕ ਕਾਲਮ ਡ੍ਰਾਪ ਕਰ ਰਹੇ ਹੋ ਜਾਂ ਡਾਟਾ ਨੂੰ ਥਾਂ-ਠਾਵਾਂ 'ਤੇ ਮੁੜ ਲਿਖ ਰਹੇ ਹੋ, ਤਾਂ ਇੱਕ ਹਕੀਕਤੀ ਜਵਾਬ ਦੀ ਮੰਗ ਕਰੋ ਜਿਵੇਂ: "Rollback restores app compatibility, but original data can't be recovered without a snapshot." ਇਹ ਇਮਾਨਦਾਰੀ ਤੁਹਾਨੂੰ ਸੁਰੱਖਿਅਤ ਰੱਖਦੀ ਹੈ।
ਸਪਸ਼ਟ ਰੋਲਬੈਕ ਟ੍ਰਿਗਰ ਮੰਗੋ ਤਾਂ ਜੋ ਕਿਸੇ ਘੜੀਲੇ ਸਮੇਂ 'ਤੇ ਕੋਈ ਵਾਦ-ਵਿਵਾਦ ਨਾ ਹੋਵੇ। ਉਦਾਹਰਨ:
ਪੂਰਾ ਰੋਲਬੈਕ ਪੈਕੇਜ ਲਾਜ਼ਮੀ ਕਰੋ, ਸਿਰਫ SQL ਨਹੀਂ: ਡਾਊਨ ਮਾਈਗ੍ਰੇਸ਼ਨ SQL (ਸਿਰਫ ਜੇ ਇਹ ਸਚਮੁਚ ਸੁਰੱਖਿਅਤ ਹੋਵੇ), ਐਪ ਸਟੈਪਸ ਜਿਨ੍ਹਾਂ ਨਾਲ ਅਨੁਕੂਲਤਾ ਬਣੀ ਰਹੇ, ਅਤੇ ਬੈਕਗ੍ਰਾਊਂਡ ਜੌਬਸ ਨੂੰ ਰੋਕਣ ਦੀ ਵਿਧੀ।
ਇਹ ਪ੍ਰਾਂਪਟ ਆਮ ਤੌਰ 'ਤੇ ਕਾਫੀ ਹੁੰਦੀ ਹੈ:
Produce a rollback plan for this migration.
Include: down migration SQL, app config/code switches needed for compatibility, and the exact order of steps.
State what can be rolled back (schema) vs what cannot (data) and what evidence we need before deciding.
Include rollback triggers with thresholds.
ਸ਼ਿਪ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਇੱਕ ਹਲਕੀ "ਸੇਫਟੀ ਸਨੈਪਸ਼ਾਟ" ਲਵੋ ਤਾਂ ਜੋ ਤੁਸੀਂ ਪਹਿਲਾਂ ਅਤੇ ਬਾਅਦ ਤੁਲਨਾ ਕਰ ਸਕੋ:
ਇਸਦੇ ਨਾਲ ਇਹ ਵੀ ਸਪਸ਼ਟ ਕਰੋ ਕਿ ਕਦੋਂ ਰੋਲਬੈਕ ਨਾ ਕੀਤਾ ਜਾਏ। ਜੇ ਤੁਸੀਂ ਕੇਵਲ nullable ਕਾਲਮ ਜੋੜਿਆ ਹੈ ਅਤੇ ਐਪ dual-writing ਕਰ ਰਹੀ ਹੈ, ਤਾਂ ਅੱਗੇ ਵਧਣਾ (hotfix ਕੋਡ, ਬੈਕਫਿਲ ਰੋਕੋ, ਫਿਰ ਰੀਸਾਰਟ) ਆਮ ਤੌਰ 'ਤੇ ਵਾਪਸੀ ਤੋਂ ਸੁਰੱਖਿਅਤ ਹੁੰਦਾ ਹੈ।
AI ਤੇਜ਼ੀ ਨਾਲ SQL ਲਿਖ ਸਕਦਾ ਹੈ, ਪਰ ਇਹ ਤੁਹਾਡੇ ਪ੍ਰੋਡਕਸ਼ਨ ਡੇਟਾਬੇਸ ਨੂੰ ਨਹੀਂ ਵੇਖਦਾ। ਜ਼ਿਆਦਾਤਰ ਫੇਲ੍ਹਿਅਰ ਉਸ ਵੇਲੇ ਹੁੰਦੇ ਹਨ ਜਦੋਂ ਪ੍ਰਾਂਪਟ ਅਸਪੱਸ਼ਟ ਹੁੰਦਾ ਹੈ ਅਤੇ ਮਾਡਲ ਖਾਲੀਆਂ ਭਰਨ ਲੱਗਦਾ ਹੈ।
ਆਮ ਜਾਲ ਇਹ ਹੈ ਕਿ ਮੌਜੂਦਾ ਸਕੀਮਾ ਛੱਡ ਦਿੱਤੀ ਜਾਂਦੀ ਹੈ। ਜੇ ਤੁਸੀਂ ਟੇਬਲ ਡਿਫਿਨੀਸ਼ਨ, ਇੰਡੈਕਸ, ਅਤੇ ਕੰਸਟਰੇਨਟ ਪੇਸਟ ਨਹੀਂ ਕਰਦੇ, ਤਾਂ ਜਨਰੇਟ ਕੀਤਾ SQL ਉਹ ਕਾਲਮ ਟਾਰਗੇਟ ਕਰ ਸਕਦਾ ਹੈ ਜੋ ਮੌਜੂਦ ਨਹੀਂ ਹਨ ਜਾਂ ਇੱਕ ਯੂਨੀਕਨੈਸ ਕਾਇਦਾ ਮਿਸ ਕਰਕੇ ਬੈਕਫਿਲ ਨੂੰ ਧੀਮਾ, ਲਾਕ-ਭਰੇ ਕੰਮ ਵਿੱਚ ਬਦਲ ਦੇਵੇ।
ਹੋਰ ਇੱਕ ਗਲਤੀ expand, backfill, ਅਤੇ contract ਨੂੰ ਇੱਕ ਹੀ ਡਿਪਲੌਇ ਵਿੱਚ ਪੈਕ ਕਰਨਾ ਹੈ। ਇਸ ਨਾਲ ਤੁਹਾਡੀ ਐਸਕੇਪ ਹੈਚ ਦੁਆਰਾ ਹਟ ਜਾਂਦੀ ਹੈ। ਜੇ ਬੈਕਫਿਲ ਲੰਮਾ ਚੱਲੇ ਜਾਂ ਅੱਧੇ-ਰਾਹ ਫੇਲ੍ਹ ਹੋ ਜਾਵੇ, ਤਾਂ ਤੁਸੀਂ ਐਸੋ ਇੱਕ ਐਪ ਨਾਲ ਫਸ ਜਾਂਦੇ ਹੋ ਜੋ ਆਖ਼ਰੀ ਸਥਿਤੀ ਦੀ ਉਮੀਦ ਕਰਦੀ ਹੈ।
ਸਭ ਤੋਂ ਆਮ ਸਮੱਸਿਆਵਾਂ:
ਇੱਕ ਵਾਸਤਵਿਕ ਉਦਾਹਰਨ: "ਕੋਲਮ ਨੂੰ ਰੀਨੇਮ ਕਰੋ ਅਤੇ ਐਪ ਅਪਡੇਟ ਕਰੋ." ਜੇ ਜਨਰੇਟ ਕੀਤੀ ਯੋਜਨਾ ਇੱਕ ਹੀ ਟ੍ਰਾਂਜ਼ੈਕਸ਼ਨ ਵਿੱਚ ਰੀਨੇਮ ਅਤੇ ਬੈਕਫਿਲ ਕਰ ਦੇਂਦੀ ਹੈ, ਇੱਕ ਧੀਮਾ ਬੈਕਫਿਲ ਲਾਈਵ ਟ੍ਰੈਫਿਕ ਨੂੰ ਤੋੜ ਸਕਦਾ ਹੈ। ਇੱਕ ਸੁਰੱਖਿਅਤ ਪ੍ਰਾਂਪਟ ਛੋਟੇ ਬੈਚ, ਸਪਸ਼ਟ ਟਾਈਮਆਊਟ, ਅਤੇ ਰੋਲਬੈਕ-ਸਾਇੱਕਪਾਇੰਟ ਮੰਗੇਗਾ।
ਸਟੇਜਿੰਗ ਉਹ ਥਾਂ ਹੈ ਜਿੱਥੇ ਤੁਸੀਂ ਉਹ ਸਮੱਸਿਆਵਾਂ ਲੱਭਦੇ ਹੋ ਜੋ ਛੋਟੀ ਡੈਵ ਡੀਬੀ 'ਤੇ ਨਹੀਂ ਦਿੱਸਦੀਆਂ: ਲੰਬੇ ਲਾਕ, ਚੌਂਕੀ ਨਲਜ਼, ਗੁੰਮ ਇੰਡੈਕਸ, ਅਤੇ ਭੁੱਲੇ ਹੋਏ ਕੋਡ ਪਾਥ।
ਪਹਿਲਾਂ, ਯਕੀਨ ਕਰੋ ਕਿ ਮਾਈਗ੍ਰੇਸ਼ਨ ਤੋਂ ਬਾਅਦ ਸਕੀਮਾ ਯੋਜਨਾ ਦੇ ਅਨੁਸਾਰ ਮਿਲਦਾ ਹੈ: ਕਾਲਮ, ਟਾਈਪ, ਡਿਫੋਲਟ, ਕੰਸਟਰੇਨਟ, ਅਤੇ ਇੰਡੈਕਸ। ਇੱਕ ਝਲਕ ਕਾਫੀ ਨਹੀਂ। ਇੱਕ ਗੁੰਮ ਹੋਇਆ ਇੰਡੈਕਸ ਇੱਕ ਸੁਰੱਖਿਅਤ ਬੈਕਫਿਲ ਨੂੰ ਧੀਮਾ ਕਰ ਸਕਦਾ ਹੈ।
ਫਿਰ ਮਾਈਗ੍ਰੇਸ਼ਨ ਨੂੰ ਇੱਕ ਹਕੀਕਤੀ dataset 'ਤੇ ਚਲਾਓ। ਇਹ ਆਦਰਸ਼ ਹੈ ਕਿ ਇਹ ਪ੍ਰੋਡਕਸ਼ਨ ਦਾ ਹਾਲ ਹੀ ਦਾ ਕੌਪੀ ਹੋਵੇ ਜਿਸ ਦੇ ਸੰਵੇਦਨਸ਼ੀਲ ਫੀਲਡ ماسਕ ਕੀਤੇ ਹੋਣ। ਜੇ ਤੁਸੀਂ ਇਹ ਨਹੀਂ ਕਰ ਸਕਦੇ, ਤਾਂ ਘੱਟੋ-ਘੱਟ ਪ੍ਰੋਡਕਸ਼ਨ ਵਾਲਿਊਮ ਅਤੇ ਹੌਟਸਪੌਟਸ ਨਾਲ ਮੈਚ ਕਰੋ (ਵੱਡੇ ਟੇਬਲ, ਵਿਆਪਕ ਰੋਜ਼, ਜ਼ਿਆਦਾ ਇੰਡੈਕਸ ਟੇਬਲ)। ਹਰ ਕਦਮ ਲਈ ਟਾਇਮਿੰਗਜ਼ ਦਰਜ ਕਰੋ ਤਾਂ ਕਿ ਪ੍ਰੋਡਕਸ਼ਨ ਵਿੱਚ ਕੀ ਉਮੀਦ ਰੱਖਣੀ ਹੈ ਸਮਝ ਆਵੇ।
ਸਟੇਜਿੰਗ ਚੈੱਕਲਿਸਟ:
ਅੰਤ ਵਿੱਚ, ਅਸਲੀ ਯੂਜ਼ਰ ਫਲੋਜ਼ ਨੂੰ ਟੈਸਟ ਕਰੋ, ਸਿਰਫ SQL ਨਹੀਂ। ਬਣਾਉ, ਅਪਡੇਟ, ਅਤੇ ਪੜ੍ਹੋ ਉਹ ਰਿਕਾਰਡ ਜਿਹੜੇ ਬਦਲਾਅ ਨਾਲ ਸਪর্শਿਤ ਹਨ। ਜੇ expand/contract ਯੋਜਨਾ ਹੈ, ਤਾਂ ਇਹ ਪੁਸ਼ਟੀ ਕਰੋ ਕਿ ਦੋਹਾਂ ਸਕੀਮਾ ਫਾਇਨਲ ਕਲੀਨਅਪ ਤੱਕ ਕੰਮ ਕਰ ਰਹੇ ਹਨ।
ਕਲਪਨਾ ਕਰੋ ਤੁਹਾਡੇ ਕੋਲ users.name ਕਾਲਮ ਹੈ ਜੋ ਪੂਰਨ ਨਾਮ ਜਿਵੇਂ "Ada Lovelace" ਰੱਖਦਾ ਹੈ। ਤੁਸੀਂ first_name ਅਤੇ last_name ਚਾਹੁੰਦੇ ਹੋ, ਪਰ ਤੁਸੀਂ ਸਾਈਨਅੱਪਸ, ਪ੍ਰੋਫਾਈਲ, ਜਾਂ ਐਡਮਿਨ ਸਕ੍ਰੀਨਜ਼ ਨੂੰ ਬਦਲਾਅ ਦੌਰਾਨ ਤੋੜ ਨਹੀਂ ਸਕਦੇ।
Expand ਕਦਮ ਨਾਲ ਸ਼ੁਰੂ ਕਰੋ ਜੋ ਸੁਰੱਖਿਅਤ ਹੈ ਭਾਵੇਂ ਕੋਈ ਕੋਡ ਬਦਲਾਅ ਅਜੇ ਰਿਲੀਜ਼ ਨਾ ਹੋਵੇ: nullable ਕਾਲਮ ਜੋੜੋ, ਪੁਰਾਣਾ ਕਾਲਮ ਰੱਖੋ, ਅਤੇ ਲੰਬੇ ਲਾਕਾਂ ਤੋਂ ਬਚੋ।
ALTER TABLE users ADD COLUMN first_name text;
ALTER TABLE users ADD COLUMN last_name text;
ਫਿਰ ਐਪ ਬਿਹੇਵਿਅਰ ਨੂੰ ਅਪਡੇਟ ਕਰੋ ਤਾਂ ਕਿ ਦੋਹਾਂ ਸਕੀਮਾਵਾਂ ਕੋਲ ਕੰਮ ਕਰ ਸਕੇ। ਰਿਲੀਜ਼ 1 ਵਿੱਚ, ਐਪ ਨਵਿਆਂ ਕਾਲਮ ਤੋਂ ਪੜھےਗਾ ਜੇ ਉਪਲਬਧ ਹੋਵਣ, ਨਹੀਂ ਤਾਂ name ਤੋਂ fallback ਲਵੇਗਾ, ਅਤੇ ਨਵੀਆਂ ਲਿਖਤਾਂ ਦੋਹਾਂ ਵਿੱਚ ਲਿਖੇ ਜਾਣ।
ਅਗਲਾ ਬੈਕਫਿਲ ਆਉਂਦਾ ਹੈ। ਇੱਕ ਬੈਚ ਜੌਬ ਚਲਾਓ ਜੋ ਪ੍ਰਤੀ ਰਨ ਛੋਟਾ ਚੰਕ ਅਪਡੇਟ ਕਰਦਾ ਹੈ, ਪ੍ਰਗਤੀ ਦਰਜ ਕਰਦਾ ਹੈ, ਅਤੇ ਸੁਰੱਖਿਅਤ ਢੰਗ ਨਾਲ ਰੁਕਿਆ ਜਾਂ ਰੀਜ਼ਿਊਮ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ। ਉਦਾਹਰਨ ਲਈ: ascending ID order ਵਿੱਚ first_name null ਵਾਲੀ users ਨੂੰ 1,000-ਦਰ-1,000 ਅਪਡੇਟ ਕਰੋ ਅਤੇ ਲੌਗ ਕਰੋ ਕਿ ਕਿੰਨੀਆਂ ਕਤਾਰਾਂ ਬਦਲੀਆਂ ਗਈਆਂ।
ਕਸੋਟੀ ਤੋਂ ਪਹਿਲਾਂ ਉਨ੍ਹਾਂ ਨਿਯਮਾਂ ਨੂੰ ਕਸੋਟੀ ਕਰੋ:
first_name ਅਤੇ last_name ਭਰਦੀਆਂ ਹਨ ਅਤੇ ਫਿਰ ਵੀ name ਸੈੱਟ ਹੁੰਦਾ ਹੈname ਹੀ ਮੌਜੂਦ ਹੋਵੇusers 'ਤੇ ਮੂਲ ਕਵੈਰੀਆਂ ਧਿਆਨਯੋਗ ਤੌਰ 'ਤੇ ਜ਼ਿਆਦਾ ਸਲੋ ਨਹੀਂ ਹਨਰਿਲੀਜ਼ 2 ਵਿੱਚ ਪੜ੍ਹਾਈਆਂ ਨੂੰ ਕੇਵਲ ਨਵੀਆਂ ਕਾਲਮਾਂ 'ਤੇ ਸਵਿੱਚ ਕਰੋ। ਉਸ ਤੋਂ ਬਾਅਦ ਹੀ constraints (ਜਿਵੇਂ SET NOT NULL) ਅਤੇ name ਨੂੰ ਡ੍ਰਾਪ ਕਰੋ, ਵਧੀਆ ਤਰੀਕੇ ਨਾਲ ਇਕ ਅਲੱਗ ਡਿਪਲੌਇ ਵਿੱਚ।
ਰੋਲਬੈਕ ਲਈ, ਇਸਨੂੰ ਬੋਰਿੰਗ ਰੱਖੋ। ਟ੍ਰਾਂਜੀਸ਼ਨ ਦੌਰਾਨ ਐਪ name ਪੜ੍ਹਦਾ ਰਹੇਗਾ, ਅਤੇ ਬੈਕਫਿਲ ਰੋਕਣਯੋਗ ਹੈ। ਜੇ ਤੁਹਾਨੂੰ ਰਿਲੀਜ਼ 2 ਵਾਪਸ ਲੈਣਾ ਪੈਣਾ ਹੈ, ਪੜ੍ਹਾਈਆਂ ਨੂੰ ਮੁੜ name ਤੇ ਸਵਿੱਚ ਕਰੋ ਅਤੇ ਨਵੀਆਂ ਕਾਲਮਾਂ ਨੂੰ ਥਾਂ 'ਤੇ ਰਹਿਣ ਦਿਓ ਜਦ ਤੱਕ ਅਸੀਂ ਥੱਲੇ ਆ ਨਿਰੱਵਿੱਕ ਨਹੀਂ ਹੁੰਦੇ।
ਹਰ ਬਦਲਾਅ ਨੂੰ ਇੱਕ ਛੋਟੇ ਰਨਬੁੱਕ ਵਾਂਗ ਲਓ। ਮਕਸਦ ਇੱਕ ਮੁਕੰਮਲ ਪ੍ਰਾਂਪਟ ਨਹੀਂ, ਸਗੋਂ ਇੱਕ ਰੁਟੀਨ ਹੈ ਜੋ ਠੀਕ ਵੇਰਵੇ ਮੰਗਦੀ ਹੈ: ਸਕੀਮਾ, ਕੰਸਟਰੇਨਟ, ਰਨ ਪਲਾਨ, ਅਤੇ ਰੋਲਬੈਕ।
ਮਿਆਰੀਕ੍ਰਿਤ ਕਰੋ ਕਿ ਹਰ ਮਾਈਗ੍ਰੇਸ਼ਨ ਬੇਨਤੀ ਵਿੱਚ ਕੀ-ਕਿਆ ਲਾਜ਼ਮੀ ਹੋਵੇ:
ਕਿਸੇ ਵੀ SQL ਨੂੰ ਚਲਾਉਣ ਤੋਂ ਪਹਿਲਾਂ ਇਹ ਫੈਸਲਾ ਕਰੋ ਕਿ ਕੌਣ ਹਰ ਕਦਮ ਦਾ ਮਾਲਕ ਹੈ। ਇਹ ਸਧਾਰਨ ਵੰਡ "ਹਰ ਕੋਈ ਸੋਚ ਰਿਹਾ ਸੀ ਕਿ ਕੋਈ ਹੋਰ ਕਰੇਗਾ" ਦੀ ਸਮੱਸਿਆ ਰੋਕਦੀ ਹੈ: ਡਿਵੈਲਪਰ ਪ੍ਰਾਂਪਟ ਅਤੇ ਮਾਈਗ੍ਰੇਸ਼ਨ ਕੋਡ ਲਈ ਮਾਲਕ ਹਨ, ਓਪਸ ਪ੍ਰੋਡਕਸ਼ਨ ਸਮੇਂ ਅਤੇ ਮਾਨੀਟਰਿੰਗ ਲਈ, QA ਸਟੇਜਿੰਗ ਵਿਵਹਾਰ ਅਤੇ ਐਜ ਕੇਸਾਂ ਦੀ ਪੁਸ਼ਟੀ ਲਈ, ਅਤੇ ਇੱਕ ਵਿਅਕਤੀ ਫਾਇਨਲ ਜਾ/ਨੋ-ਗੋ ਲਈ।
ਜੇ ਤੁਸੀਂ ਚੈਟ ਰਾਹੀਂ ਐਪ ਬਣਾਉਂਦੇ ਹੋ, ਤਾਂ SQL ਜਨਰੇਟ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਕ੍ਰਮ ਨੂੰ ਲਿਖਣਾ ਮਦਦ ਕਰਦਾ ਹੈ। Koder.ai ਵਰਤਣ ਵਾਲੀ ਟੀਮਾਂ ਲਈ, Planning Mode ਇਸ ਕ੍ਰਮ ਨੂੰ ਲਿਖਣ ਲਈ ਕੁਦਰਤੀ ਥਾਂ ਹੈ, ਅਤੇ ਸਨੈਪਸ਼ਾਟਸ ਤੇ ਰੋਲਬੈਕ ਵਿਸ਼ੇ ਵਿਚਾਰਭਾਰ ਨੂੰ ਘਟਾ ਸਕਦੇ ਹਨ ਜੇ ਰੋਲਆਊਟ ਦੌਰਾਨ ਕੁਝ ਅਣਉਮੀਦਿਤ ਹੁੰਦਾ ਹੈ।
ਸ਼ਿਪ ਕਰਨ ਤੋਂ ਬਾਅਦ, ਕਿਰਪਾ ਕਰਕੇ ਕਲੀਨਅਪ (contract) ਤੁਰੰਤ ਸ਼ਡਿਊਲ ਕਰੋ ਤਾਂ ਕਿ ਪੁਰਾਣੇ ਕਾਲਮ ਅਤੇ ਅਸਥਾਈ ਅਨੁਕੂਲਤਾ ਕੋਡ ਮਹੀਨਿਆਂ ਤੱਕ ਨਾ ਰਹਿ ਜਾਣ।
A schema change is risky when app code, database state, and deployment timing stop matching.
Common failure modes:
Use an expand/contract approach:
This keeps both old and new app versions working during rollout.
Because the model can generate SQL that is valid but unsafe for your workload.
Typical AI-specific risks:
Treat AI output as a draft and require a run plan, checks, and rollback steps.
Include only the facts the migration depends on:
CREATE TABLE snippets (plus indexes, FKs, UNIQUE/CHECK constraints, triggers)Default rule: separate them.
A practical split:
Bundling everything makes failures harder to diagnose and roll back.
Prefer this pattern:
ADD COLUMN ... NULL with no default (fast)NOT NULL only after verificationAdding a non-null default can be risky on some versions because it may rewrite the whole table. If you need an immediate default, ask for lock/runtime notes and a safer fallback.
Ask for:
CREATE INDEX CONCURRENTLY for large/hot tablesFor verification, include a quick check that the index exists and is used (for example, compare an EXPLAIN plan before/after in staging).
Use NOT VALID first, then validate later:
NOT VALID so the initial step is less disruptiveVALIDATE CONSTRAINT in a separate step when you can watch itThis still enforces the FK for new writes, while letting you control when the expensive validation happens.
A good backfill is batched, idempotent, and restartable.
Practical requirements:
WHERE new_col IS NULL)Default rollback goal: restore app compatibility fast, even if data isn’t perfectly undone.
A workable rollback plan should include:
Often the safest rollback is switching reads back to the old field while leaving new columns in place.
This prevents guessing and forces the right ordering.
This makes backfills survivable under real traffic.