-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add support for COPY ... FROM STDIN and COPY ... TO STDOUT statements in PostgreSQL #36
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
Comments
This could be implemented as an inherent method on |
Marking this as a good contribution for someone looking to contribute to the internals. The following is my initial thoughts on what a good API would look like. impl PgCopyOut {
// Returns a cursor over the rows of the data stream
fn into_cursor(self) -> PgCursor;
// Returns a stream of bytes
fn into_stream(self) -> impl Stream<Item = u8>;
fn into_async_read(self) -> impl AsyncRead;
}
impl PgCopyIn {
// Expect a stream of bytes
fn into_sink(self) -> impl Sink<Item = u8>;
fn into_async_write(self) -> impl AsyncWrite;
}
pub trait PgExecutorExt: Executor {
// Expected COPY TO ... STDOUT
fn copy_out<'q, 'e, E>(
&'e mut self,
statement: &'q str,
) -> PgCopyOut<'q, 'e>;
// Expected COPY FROM ... STDIN
fn copy_in<'q, 'e>
&'e mut self,
statement: &'q str,
) -> PgCopyIn<'q, 'e>;
}
// Copy from one database to another
let rx = con1.copy_out("COPY articles TO STDOUT");
let tx = con2.copy_in("COPY articles FROM STDIN");
rx.into_stream().forward(tx.into_sink()).await?; |
@mehcode one hiccup with |
Good point. We just get a stream of |
We can have a similar API but I'm thinking specialized types that clearly document that they're semi-unchecked. Maybe on top of that we can have a proc-macro API that looks at the table schema and makes it "safe" or something. |
Additionally, the main API probably shouldn't take raw statements but instead either a table name and list of columns or the data source query. fn copy_out(&mut self, table; &str, columns: impl IntoIterator<Item = &str>) -> PgCopyOut
/// Accepts just the SELECT/INSERT/UPDATE/DELETE RETURNING portion
fn copy_out_with(&mut self, query: &str) -> PgCopyOut
fn copy_in(&mut self, table: &str, columns: impl IntoIterator<Item = &str>) -> PgCopyIn I'd be okay with
I'm assuming the types that |
SQLx is not a query builder (yet). I'm really hesitant to provide an API on It's simple to die immediately if they don't send the right command as postgres responds in a specific way and tells us the details about their copy command. |
|
I mainly suggest not just taking the full statement because by default |
I don't disagree. My point is that something like query construction is better suited to a DSL if/when we get it: // Not sure a good name for the _ method
let cin: PgCopyIn = copy_in("table").columns(&["a", "b"])._(&mut conn).await?; Macro version perhaps: let cin: PgCopyIn = copy_in!(table(a, b))._(&mut conn).await?; |
Maybe we should do a builder here then. There's not really that much to configure if you're using binary format, it's just whether or not you supply a column list or subquery. |
I think the Executor trait should still be the low-level operational trait that takes the raw query. I'm not against adding a DSL on top of it to make things simpler. Just that we should do this task in phases.
|
Yeah, I can get behind that. |
For the first step, should we still do |
Any news about this?, is there something i can do meanwhile to make a massive database ingest, thanks |
Hi!
COPY
is the most efficient way to import data to PostgreSQL database (it is less flexible thanINSERT
, but has significantly less overhead).https://www.postgresql.org/docs/current/sql-copy.html
https://www.postgresql.org/docs/current/populate.html#POPULATE-COPY-FROM
It would be great to have a low-level interface to stream data to/from PostgreSQL using
COPY ... FROM STDIN
andCOPY ... TO STDOUT
statements. For example, similar to https://docs.rs/tokio-postgres/0.5.1/tokio_postgres/struct.Client.html#method.copy_in and https://docs.rs/tokio-postgres/0.5.1/tokio_postgres/struct.Client.html#method.copy_out.The text was updated successfully, but these errors were encountered: