NPGSQL: Streaming risultati di query di Postgres?
-
19-09-2019 - |
Domanda
Ho un grande tavolo (2.000.000 file) e mi piacerebbe stampare ogni record sullo schermo, uno alla volta, senza caricare l'intera tabella in memoria.
//pseudo code
var cmd = new NpgSQLCommand();
cmd.CommandText = "SELECT * FROM mytable;"
IReader reader = cmd.ExecuteReader(); //blocks until the entire set is returned
while(reader.Read()) //ideally each call to read loads more results from the db.
{
// print record name
}
Quindi, come indicato nel codice qui sopra, l'ExecuteReader () non continua fino a quando l'intero set viene caricato in memoria. Come faccio a cambiare questo comportamento in modo che i risultati sono in streaming?
Grazie
ETA: Anche se questo sembra come compiti a casa, non lo è. È solo un modo più semplice per descrivere un problema che implica la lettura un'intera tabella con una singola query ma elaborazione dei risultati di una riga alla volta.
ETA x2:
Da npgsql
Attenzione: C'è un problema noto quando si chiama ExecuteReader e tabelle di grandi dimensioni. Attualmente versione 1 di Npgsql riceve tutti i dati da tavolo prima di tornare. Se si verificano cattiva performance in questi casi, potrebbe essere necessario utilizzare un cursore del server per scorrere le righe. Per questo, è possibile utilizzare un codice come il seguente:
Soluzione 2
Ok, sembra che questo è un problema noto con npgsql 1.0:
La soluzione è utilizzare un cursore del server:
using System;
using System.Data;
using Npgsql;
public static class NpgsqlUserManual
{
public static void Main(String[] args)
{
NpgsqlConnection conn = new NpgsqlConnection("Server=127.0.0.1;Port=5432;User Id=joe;Password=secret;Database=joedata;");
conn.Open();
NpgsqlCommand command = new NpgsqlCommand("select version()", conn);
String serverversion;
try
{
serverversion = (String)command.ExecuteScalar();
Console.WriteLine("PostgreSQL server version: {0}", serverversion);
}
finally
{
conn.Close();
}
}
}
Altri suggerimenti
Npgsql2 ora gestisce grandi gruppi di risultati molto migliori. Essa non carica tutti i dati in memoria. Quindi, non è necessario utilizzare più un cursore sul lato server.
Spero che aiuta.
Francisco Figueiredo Jr. Npgsql Sviluppatore
Il modo più semplice per farlo è:
COPY ( select * from Table) TO STDOUT
Controlla la sintassi di copia per vedere come stamparlo in formato .csv o qualsiasi altro formato se avete bisogno di ...
Per stampare l'intera tabella con nome di colonna e l'utilizzo del valore seguente codice:
using (var conn = new NpgsqlConnection("Host=IPADDRESS;Username=USER;Password=PASS;Database=DBNAME;"))
{
conn.Open();
using (var cmd = new NpgsqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = "SELECT * FROM TABLE_NAME";
StringBuilder str;
int count;
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
str = new StringBuilder();
count = 0;
while (count < reader.FieldCount) {
str.Append(reader.GetName(count) + ": " + reader.GetValue(count));
if ((count + 1) < reader.FieldCount)
{
str.Append(", ");
}
count++;
}
Console.WriteLine(str.ToString());
Console.WriteLine("====================");
}
}
}