mirror of
https://github.com/jbranchaud/til
synced 2026-01-20 23:48:02 +00:00
Compare commits
2 Commits
81246ecb7b
...
20096fb81e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20096fb81e | ||
|
|
9a3d2277cb |
@@ -10,7 +10,7 @@ pairing with smart people at Hashrocket.
|
|||||||
|
|
||||||
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
|
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
|
||||||
|
|
||||||
_1204 TILs and counting..._
|
_1206 TILs and counting..._
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -609,6 +609,7 @@ _1204 TILs and counting..._
|
|||||||
- [Get The Size Of An Index](postgres/get-the-size-of-an-index.md)
|
- [Get The Size Of An Index](postgres/get-the-size-of-an-index.md)
|
||||||
- [Getting A Slice Of An Array](postgres/getting-a-slice-of-an-array.md)
|
- [Getting A Slice Of An Array](postgres/getting-a-slice-of-an-array.md)
|
||||||
- [Group By The Result Of A Function Call](postgres/group-by-the-result-of-a-function-call.md)
|
- [Group By The Result Of A Function Call](postgres/group-by-the-result-of-a-function-call.md)
|
||||||
|
- [Idempotent Inserts](postgres/idempotent-inserts.md)
|
||||||
- [Include All Queries In The Log File](postgres/include-all-queries-in-the-log-file.md)
|
- [Include All Queries In The Log File](postgres/include-all-queries-in-the-log-file.md)
|
||||||
- [Insert A Bunch Of Records With Generate Series](postgres/insert-a-bunch-of-records-with-generate-series.md)
|
- [Insert A Bunch Of Records With Generate Series](postgres/insert-a-bunch-of-records-with-generate-series.md)
|
||||||
- [Insert Just The Defaults](postgres/insert-just-the-defaults.md)
|
- [Insert Just The Defaults](postgres/insert-just-the-defaults.md)
|
||||||
@@ -914,6 +915,7 @@ _1204 TILs and counting..._
|
|||||||
|
|
||||||
### Remix
|
### Remix
|
||||||
|
|
||||||
|
- [Get Query Params From The Request URL](remix/get-query-params-from-the-request-url.md)
|
||||||
- [Relative And Absolute Paths In Links](remix/relative-and-absolute-paths-in-links.md)
|
- [Relative And Absolute Paths In Links](remix/relative-and-absolute-paths-in-links.md)
|
||||||
- [Run The Development Server From Another Port](remix/run-the-development-server-from-another-port.md)
|
- [Run The Development Server From Another Port](remix/run-the-development-server-from-another-port.md)
|
||||||
- [Set The Title Of A Page](remix/set-the-title-of-a-page.md)
|
- [Set The Title Of A Page](remix/set-the-title-of-a-page.md)
|
||||||
|
|||||||
29
postgres/idempotent-inserts.md
Normal file
29
postgres/idempotent-inserts.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# Idempotent Inserts
|
||||||
|
|
||||||
|
I'm writing a bunch of records from one table to another using
|
||||||
|
[`insert`](https://www.postgresql.org/docs/current/sql-insert.html). This is
|
||||||
|
part of a process to swap out a massive table with an identical version that
|
||||||
|
has a fraction of the records.
|
||||||
|
|
||||||
|
I want to copy a subset of rows from the primary table to the replacement table
|
||||||
|
that meet certain criteria. This query should be re-runnable and idempotent.
|
||||||
|
That way I can run it, investage the replacement table, and then run it again
|
||||||
|
before swapping out the tables. This helps ensure I don't miss anything.
|
||||||
|
|
||||||
|
Such an idempotent query can be written with the help of the `on conflict`
|
||||||
|
clause.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
insert into replacement_table
|
||||||
|
select * from original_table
|
||||||
|
where created_at > (now() - '3 months'::interval)
|
||||||
|
on conflict do nothing;
|
||||||
|
```
|
||||||
|
|
||||||
|
If I run that multiple times, it skips over any records that would otherwise
|
||||||
|
cause a conflict. The unique primary key column is usually what determines a
|
||||||
|
conflicting record.
|
||||||
|
|
||||||
|
Without the `on conflict do nothing`, trying to run this `insert` multiple
|
||||||
|
times will fail on subsequent runs when it tries to re-insert rows with primary
|
||||||
|
keys it has already inserted.
|
||||||
33
remix/get-query-params-from-the-request-url.md
Normal file
33
remix/get-query-params-from-the-request-url.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Get Query Params From The Request URL
|
||||||
|
|
||||||
|
You can enable a Remix route to respond to query params in the URL in a
|
||||||
|
`loader` function. To do this, you first need to parse them out of the request
|
||||||
|
URL.
|
||||||
|
|
||||||
|
The arguments to the `loader` function will include the `request` object which
|
||||||
|
itself includes the `url`. From there, you can use the browser's [`URL`
|
||||||
|
constructor](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) to parse
|
||||||
|
and extract query params (i.e. search params).
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import type { LoaderFunction } from "@remix-run/node";
|
||||||
|
|
||||||
|
export async function loader({ request }): LoaderFunction {
|
||||||
|
const url = new URL(request.url);
|
||||||
|
const query = url.searchParams.get("q");
|
||||||
|
|
||||||
|
results = await getResultsForQuery({ query });
|
||||||
|
|
||||||
|
return { result };
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The constructed `URL` object responds to
|
||||||
|
[`searchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URL/searchParams)
|
||||||
|
which you can call `get()` on to get a specific query param value. This uses
|
||||||
|
the [`URLSearchParams`
|
||||||
|
API](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams).
|
||||||
|
|
||||||
|
In the above case, we are able to grab the value of the `q` query param.
|
||||||
|
|
||||||
|
[source](https://remix.run/docs/en/v1/guides/data-loading#url-search-params)
|
||||||
Reference in New Issue
Block a user