# How to quickly bulk insert into postgres 1

**URL:** https://discourse.julialang.org/t/how-to-quickly-bulk-insert-into-postgres-1/27784
**Category:** Data
**Created:** [August 21, 2019, 4:17am UTC](https://discourse.julialang.org/t/how-to-quickly-bulk-insert-into-postgres-1/27784 "2019-08-21T04:17:40Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![datnt2509](https://avatars.discourse-cdn.com/v4/letter/d/b77776/32.png) [@datnt2509](https://discourse.julialang.org/u/datnt2509)
#### Post date: [August 21, 2019, 4:17am UTC](https://discourse.julialang.org/t/how-to-quickly-bulk-insert-into-postgres-1/27784/1 "2019-08-21T04:17:40Z")

</div>

This is sort of a shot in the dark, I don’t have any reason to believe there’s a better solution to this but I thought I’d give it a try.

I’m trying to insert data into tables on a postgres database. I’m using the excellent doing

```julia
Data.stream!(df, LibPQ.Statement, cnxn, str)

```

where `str` is an insert statement and `df` is the `DataFrame` I want to upload.

Everything works perfectly fine except that it is _horrifyingly_ slow. It’s taking it something like 20 minutes to upload just `5e4` rows. I know that it’s not a connection speed issue since I get plenty of bandwidth on queries. It also seems highly unlikely that this is a Julia or LibPQ performance issue (other than that I might be using a sub-optimal function for doing this).

Does anyone know of some approach that’s not incredibly slow? I feel like this can’t possibly be the way people populate postgres databases…

---

<div class="post-metadata">

### Author: ![Nosferican](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nosferican/32/9275_2.png) [@Nosferican](https://discourse.julialang.org/u/Nosferican)
#### Post date: [August 21, 2019, 4:28am UTC](https://discourse.julialang.org/t/how-to-quickly-bulk-insert-into-postgres-1/27784/2 "2019-08-21T04:28:04Z")

</div>

I haven’t benchmark my application, but I have done it directly for each row…

```julia
@unpack isPrivate, databaseId, nameWithOwner, createdAt,
            isArchived, isFork, isMirror = node
node.isPrivate && return
execute(conn,
        """insert into universe.github_repos values(
           '$databaseId', '$nameWithOwner', '$createdAt',
            $isArchived, $isFork, $isMirror,
           '$license', '$created_at', '$as_of'
           )
           on conflict (id) do update set
           slug = excluded.slug,
           is_archived = excluded.is_archived,
           is_fork = excluded.is_fork,
           is_mirror = excluded.is_mirror,
           spdx = excluded.spdx,
           created_at = excluded.created_at,
           as_of = excluded.as_of
           """)

```

Have you compared it to doing it by row (DataFrames are row iterables so you can use the for row)

---

<div class="post-metadata">

### Author: ![fborda](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fborda/32/8654_2.png) [@fborda](https://discourse.julialang.org/u/fborda)
#### Post date: [August 21, 2019, 12:38pm UTC](https://discourse.julialang.org/t/how-to-quickly-bulk-insert-into-postgres-1/27784/3 "2019-08-21T12:38:25Z")

</div>

DataStreams is deprecated, you should use the native LibPQ methods such as LibPQ.load!:

```julia
LibPQ.load!(df, conn, insert_str)

```

---

<div class="post-metadata">

### Author: ![johann.spies](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johann.spies/32/8805_2.png) [@johann.spies](https://discourse.julialang.org/u/johann.spies)
#### Post date: [August 29, 2019, 2:12pm UTC](https://discourse.julialang.org/t/how-to-quickly-bulk-insert-into-postgres-1/27784/4 "2019-08-29T14:12:54Z")

</div>

Or

```julia
LibPQ.CopyIn

```
