Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Documentation and Test-Case for DataFrame Upload using CSV.RowIterator #186

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
6 changes: 4 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ TimeZones = "f269a46b-ccf7-5d73-abea-4c690281aa53"
[compat]
BinaryProvider = "0.5"
CEnum = "0.2"
DataFrames = "0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20"
CSV = "0.6.2"
lungben marked this conversation as resolved.
Show resolved Hide resolved
DataFrames = "0.21"
Decimals = "0.4.1"
DocStringExtensions = "0.8.0"
Infinity = "0.2"
Expand All @@ -37,8 +38,9 @@ TimeZones = "0.9.2, 0.10, 0.11, 1"
julia = "1"

[extras]
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "DataFrames"]
test = ["Test", "DataFrames", "CSV"]
20 changes: 20 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,26 @@ LibPQ.load!(
"INSERT INTO libpqjl_test (no_nulls, yes_nulls) VALUES (\$1, \$2);",
)

using DataFrames
lungben marked this conversation as resolved.
Show resolved Hide resolved
no_nulls = map(string, 'a':'z')
yes_nulls = Union{String, Missing}[isodd(Int(c)) ? string(c) : missing for c in 'a':'z']
data = DataFrame(no_nulls=no_nulls, yes_nulls=yes_nulls)

execute(conn, "DELETE FROM libpqjl_test;")

using CSV
"""
Function for upload of a Tables.jl compatible data structure (e.g. DataFrames.jl) into the db.
"""
function load_by_copy!(table, con:: LibPQ.Connection, tablename:: AbstractString)
iter = CSV.RowWriter(table)
column_names = first(iter)
copyin = LibPQ.CopyIn("COPY $tablename ($column_names) FROM STDIN (FORMAT CSV, HEADER);", iter)
execute(con, copyin)
end

load_by_copy!(data, conn, "libpqjl_test")

close(conn)
```

Expand Down
46 changes: 46 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ using Memento.TestUtils
using OffsetArrays
using TimeZones
using Tables
using CSV

Memento.config!("critical")

Expand All @@ -31,6 +32,27 @@ macro test_nolog_on_windows(ex...)
end
end

"""
load_by_copy!(table, con:: LibPQ.Connection, tablename:: AbstractString)

Fast data upload using the PostgreSQL `COPY FROM STDIN` method, which is usually much faster,
especially for large data amounts, than SQL Inserts.

`table` must be a Tables.jl compatible data structure.

All columns given in `table` must have corresponding fields in the target DB table,
the order of the columns does not matter.

Columns in the target DB table, which are not provided by the input `table`, are filled
with `null` (provided they are nullable).
"""
function load_by_copy!(table, con:: LibPQ.Connection, tablename:: AbstractString)
iter = CSV.RowWriter(table)
column_names = first(iter)
copyin = LibPQ.CopyIn("COPY $tablename ($column_names) FROM STDIN (FORMAT CSV, HEADER);", iter)
execute(con, copyin)
lungben marked this conversation as resolved.
Show resolved Hide resolved
end

@testset "LibPQ" begin

@testset "ConninfoDisplay" begin
Expand Down Expand Up @@ -317,6 +339,30 @@ end
@test isequal(table_data, data)
close(result)

# testing loading to database using CSV.jl row iterator
result = execute(
lungben marked this conversation as resolved.
Show resolved Hide resolved
conn,
"DELETE FROM libpqjl_test;";
throw_error=true,
)
close(result)

result = load_by_copy!(data, conn, "libpqjl_test")
@test isopen(result)
@test status(result) == LibPQ.libpq_c.PGRES_COMMAND_OK
@test isempty(LibPQ.error_message(result))
close(result)

result = execute(
conn,
"SELECT no_nulls, yes_nulls FROM libpqjl_test ORDER BY no_nulls ASC;";
throw_error=true
)
table_data = DataFrame(result)
@test isequal(table_data, data)
close(result)


close(conn)
end

Expand Down