<span style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">
  <p dir="auto">In my own projects, we use a different approach for data migrations.</p>
<ul dir="auto">
<li>First, we avoid using rails built-in database migrations. These are great for structure changes, but not for data changes, since they can't be tested. And there's often some edge cases that we want to have confidence about before we run the data migration and tests are the foundation for confidence.</li>
<li>We create a job to migrate the data, so that it runs in a background process. We have a rake task that simply queues the job and nothing else. This is because rake tasks are convenient for us to run, but again are very hard to test. Jobs are easy to test.</li>
<li>We have a separate queue for slow jobs, with a separate set of workers, so that if it takes e.g. 10min to run we are still sending out confirmation emails in the meantime.</li>
<li>For the task itself, we write it in a way that it can be retried multiple times. So for example we only select the objects that have not yet been migrated (e.g. <code class="notranslate">Note.where(description: nil).in_batches</code>) so that if the job is retried, it starts from where it left off, not from the start again.</li>
</ul>
<p dir="auto">We do this because in so many cases either we forgot about an edge case but picked it up in testing, or there turns out to be some unexpected data that messes things up (an example would be a note with no comments, even if there's no way that could have happened, in theory, somehow it always does). It also avoid any worries about locks, long-running transactions, transactions with large amounts of uncommitted changes, timeouts, network interruptions, db process restarts and so on.</p>
<p dir="auto">I say all this to provide an alternative approach that I know works. But in this case, since <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/tomhughes/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/tomhughes">@tomhughes</a> will be running the actual migration process, whatever approach he prefers is what we should do!</p><p style="font-size:small;-webkit-text-size-adjust:none;color:#666;">—<br />Reply to this email directly, <a href="https://github.com/openstreetmap/openstreetmap-website/pull/5667#issuecomment-2659898440">view it on GitHub</a>, or <a href="https://github.com/notifications/unsubscribe-auth/AAK2OLIZX7KTCL2D3VBN4ML2PYR63AVCNFSM6AAAAABXCOPTA2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMNJZHA4TQNBUGA">unsubscribe</a>.<br />You are receiving this because you are subscribed to this thread.<img src="https://github.com/notifications/beacon/AAK2OLJ45IUWIWOSMCKYIXT2PYR63A5CNFSM6AAAAABXCOPTA2WGG33NNVSW45C7OR4XAZNMJFZXG5LFINXW23LFNZ2KUY3PNVWWK3TUL5UWJTU6RLKEQ.gif" height="1" width="1" alt="" /><span style="color: transparent; font-size: 0; display: none; visibility: hidden; overflow: hidden; opacity: 0; width: 0; height: 0; max-width: 0; max-height: 0; mso-hide: all">Message ID: <span><openstreetmap/openstreetmap-website/pull/5667/c2659898440</span><span>@</span><span>github</span><span>.</span><span>com></span></span></p>
</span>


<div style="display: flex; flex-wrap: wrap; white-space: pre-wrap; align-items: center; "><img alt="gravitystorm" height="20" width="20" style="border-radius:50%; margin-right: 4px;" decoding="async" src="https://avatars.githubusercontent.com/u/360803?s=20&v=4" /><strong>gravitystorm</strong> left a comment <a href="https://github.com/openstreetmap/openstreetmap-website/pull/5667#issuecomment-2659898440">(openstreetmap/openstreetmap-website#5667)</a></div>
<p dir="auto">In my own projects, we use a different approach for data migrations.</p>
<ul dir="auto">
<li>First, we avoid using rails built-in database migrations. These are great for structure changes, but not for data changes, since they can't be tested. And there's often some edge cases that we want to have confidence about before we run the data migration and tests are the foundation for confidence.</li>
<li>We create a job to migrate the data, so that it runs in a background process. We have a rake task that simply queues the job and nothing else. This is because rake tasks are convenient for us to run, but again are very hard to test. Jobs are easy to test.</li>
<li>We have a separate queue for slow jobs, with a separate set of workers, so that if it takes e.g. 10min to run we are still sending out confirmation emails in the meantime.</li>
<li>For the task itself, we write it in a way that it can be retried multiple times. So for example we only select the objects that have not yet been migrated (e.g. <code class="notranslate">Note.where(description: nil).in_batches</code>) so that if the job is retried, it starts from where it left off, not from the start again.</li>
</ul>
<p dir="auto">We do this because in so many cases either we forgot about an edge case but picked it up in testing, or there turns out to be some unexpected data that messes things up (an example would be a note with no comments, even if there's no way that could have happened, in theory, somehow it always does). It also avoid any worries about locks, long-running transactions, transactions with large amounts of uncommitted changes, timeouts, network interruptions, db process restarts and so on.</p>
<p dir="auto">I say all this to provide an alternative approach that I know works. But in this case, since <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/tomhughes/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/tomhughes">@tomhughes</a> will be running the actual migration process, whatever approach he prefers is what we should do!</p>

<p style="font-size:small;-webkit-text-size-adjust:none;color:#666;">—<br />Reply to this email directly, <a href="https://github.com/openstreetmap/openstreetmap-website/pull/5667#issuecomment-2659898440">view it on GitHub</a>, or <a href="https://github.com/notifications/unsubscribe-auth/AAK2OLIZX7KTCL2D3VBN4ML2PYR63AVCNFSM6AAAAABXCOPTA2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMNJZHA4TQNBUGA">unsubscribe</a>.<br />You are receiving this because you are subscribed to this thread.<img src="https://github.com/notifications/beacon/AAK2OLJ45IUWIWOSMCKYIXT2PYR63A5CNFSM6AAAAABXCOPTA2WGG33NNVSW45C7OR4XAZNMJFZXG5LFINXW23LFNZ2KUY3PNVWWK3TUL5UWJTU6RLKEQ.gif" height="1" width="1" alt="" /><span style="color: transparent; font-size: 0; display: none; visibility: hidden; overflow: hidden; opacity: 0; width: 0; height: 0; max-width: 0; max-height: 0; mso-hide: all">Message ID: <span><openstreetmap/openstreetmap-website/pull/5667/c2659898440</span><span>@</span><span>github</span><span>.</span><span>com></span></span></p>

<script type="application/ld+json">[
{
"@context": "http://schema.org",
"@type": "EmailMessage",
"potentialAction": {
"@type": "ViewAction",
"target": "https://github.com/openstreetmap/openstreetmap-website/pull/5667#issuecomment-2659898440",
"url": "https://github.com/openstreetmap/openstreetmap-website/pull/5667#issuecomment-2659898440",
"name": "View Pull Request"
},
"description": "View this Pull Request on GitHub",
"publisher": {
"@type": "Organization",
"name": "GitHub",
"url": "https://github.com"
}
}
]</script>