【问题标题】:Dump postgresql table to XML file将 postgresql 表转储到 XML 文件
【发布时间】:2018-05-10 15:31:00
【问题描述】:

所以这是一个相对简单的问题。我有一个 postgresql 表,我需要将其转储到本地计算机上的 xml 文件中。我已经阅读了https://www.postgresql.org/docs/current/static/functions-xml.htmlhttps://www.postgresql.org/docs/9.4/static/sql-copy.html 的所有文档,并通过 psql 命令行提出了以下命令:

COPY (SELECT table_to_xml(SELECT FROM Database public.'table', true, false, '')) to 'C:/users/me/file.xml';

但是,我在“FROM”处或附近不断收到语法错误。在过去的一个小时里,我搜索了每一个看起来有用的 SO 链接 (Postgresql tables exists, but getting "relation does not exist" when querying | Cannot simply use PostgreSQL table name ("relation does not exist") | using copy in postgresql? | Postgres Data to XML) 和每一个听起来很像我需要的 YouTube 视频,但无济于事。我尝试过使用和不使用 FROM 语句,尝试在 FROM 前面使用 SELECT *,等等......没有运气。一定有一些非常简单的东西我错过了。有什么想法吗?

【问题讨论】:

  • 您能否提供以下输出:SELECT * FROM information_schema.tables where table_name = 'your_table_name'
  • 很好奇,table_to_xml() 查询在复制到文本文件之前是否有效?
  • @Vivek 当我在我的 PGAdmin 4 上执行查询 SELECT * FROM information_schema.tables where table_name = 'your_table_name' 时,我得到以下结果: 一个有很多标题的表,只有一行。标题是table_catalog(数据库名称),table_schema(公共),table_name(我的表的名称),table_type(BASE TABLE)等......其余为空
  • 没有将 public 作为数据库名称,而是将返回的值作为数据库,这一切都在尝试,因为我现在没有 pg 会话
  • @Vivek 好消息和坏消息...好消息是我尝试按照您的建议执行命令 COPY (SELECT table_to_xml(Database.'table', true, false, ''))到'C:/users/me/file.xml';它并没有给我一个错误......但是没有创建文件,并且从我的任务管理器的外观来看,没有其他任何事情发生。

标签: sql xml database postgresql


【解决方案1】:

试试这个,好像语法不对,你试过了。

COPY (SELECT table_to_xml('table', true, false, '')) to 'C:/users/me/file.xml';

另一种,你可以试试:

psql -p5432 db_name \copy (SELECT table_to_xml('table', true, false, '')) TO 'C:/users/me/file.xml';

【讨论】:

  • 感谢您的快速回答,但我已经尝试过了。我得到的错误是,当它存在时,该关系不存在。这就是为什么我将 Database public.'table' 部分添加到原始查询中。如果我尝试 COPY (SELECT table_to_xml(Database public.'table', true, false, '')) 到 'C:\users\me\file.xml';我在“public”处或附近收到语法错误
  • 你能改用'public.table'吗
  • 我还添加了另一种方法来做同样的事情,使用“psql”命令也可以。
  • 我尝试了您的两个建议,但均无济于事。我仍然收到关系不存在的错误。我已经三次检查它是否拼写正确并在我创建它的情况下准确输入......我不明白它如何仍然找不到关系。 PGAdmin 工具中是否有一些设置我可以设置以使其识别关系?
【解决方案2】:

好的,所以更新。在我一天的大部分时间都在为此苦苦挣扎之后,我想出了一个部分解决方案。使用来自这里和Permission denied when trying to import a CSV file from PGAdmin 的信息,我能够获得在 PGAdmin 4 中工作的命令......

COPY (SELECT table_to_xml('table_name', true, false, '')) to 'C:\XML\Table.xml';

上面的命令在 PGAdmin 中运行时显然会做一些我只假设是我想要的事情。如果我使用较小的数据集,我没有时间检查它是否真的创建了表的工作 XML 文件。然而,如果我按照前面提到的链接中的说明创建一个包含空白 XML 文件的文件夹,并设置权限以允许每个人读取/写入该命令执行的文件夹。然而,它使用了大量的内存。为了将一个大小仅为 2GB 的表写入 XML,程序在崩溃之前消耗了我所有的 36GB 内存。我没有时间继续测试这个,因为我发现我可以到达我需要使用转储到文本文件的地方。无论如何,我希望这对某人有所帮助。

【讨论】:

    【解决方案3】:

    复制语句对我不起作用 - 内存不足。
    不过,使用 C# 导出效果很好(这仍然会将所有数据加载到内存中):

    public static void DataToXML()
    {
        Npgsql.NpgsqlConnectionStringBuilder csb = new Npgsql.NpgsqlConnectionStringBuilder();
        csb.Database = "YourDB";
        csb.Host = "localhost";
        csb.Port = 5432;
        csb.IntegratedSecurity = true;
        csb.Username = "postgres";
        // csb.Password = "";
    
    
        using (System.Data.DataTable dt = new System.Data.DataTable())
        {
    
            dt.TableName = "record";
    
            using (System.Data.DataSet ds = new System.Data.DataSet("geoip_blocks_temp"))
            {
                ds.Tables.Add(dt);
                // dt.Namespace = "foo";
    
                using (System.Data.Common.DbConnection con = Npgsql.NpgsqlFactory.Instance.CreateConnection())
                {
                    con.ConnectionString = csb.ConnectionString;
    
                    using (System.Data.Common.DbCommand cmd = con.CreateCommand())
                    {
                        cmd.CommandText = "SELECT * FROM geoip.geoip_blocks_temp";
    
                        using (System.Data.Common.DbDataAdapter da = Npgsql.NpgsqlFactory.Instance.CreateDataAdapter())
                        {
                            da.SelectCommand = cmd;
    
                            if (con.State != System.Data.ConnectionState.Open)
                                con.Open();
    
                            da.Fill(dt);
    
                            if (con.State != System.Data.ConnectionState.Open)
                                con.Close();
                        } // End Using da 
    
                    } // End Using cmd 
    
                } // End Using con 
    
    
                //using (System.IO.Stream fs = System.IO.File.OpenWrite(@"D:\geoip_blocks_temp.xml"))
                //{
                //    using (System.IO.TextWriter sw = new System.IO.StreamWriter(fs, System.Text.Encoding.UTF8))
                //    {
                //        // System.IO.StringWriter sw = new System.IO.StringWriter();
                //        // dt.WriteXml(sw, System.Data.XmlWriteMode.IgnoreSchema);
                //        dt.WriteXml(sw, System.Data.XmlWriteMode.IgnoreSchema);
                //    } // End Using sw 
    
                //} // End Using fs 
    
    
                System.Xml.XmlWriterSettings xs = new System.Xml.XmlWriterSettings();
                xs.Indent = true;
                xs.IndentChars = "    ";
                xs.NewLineChars = System.Environment.NewLine;
                xs.OmitXmlDeclaration = false;
                // xs.Encoding = System.Text.Encoding.UTF8; // doesn't work with pgsql 
                xs.Encoding = new System.Text.UTF8Encoding(false);
    
                // <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
                using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(@"D:\geoip_blocks_temp.xml", xs))
                {
                    dt.WriteXml(writer, System.Data.XmlWriteMode.IgnoreSchema);
                }
    
                System.Console.WriteLine(dt.Rows.Count);
            } // End Using ds 
    
        } // End Using dt 
    
    } // End Sub DataToXML 
    

    或者更节省内存:

    public static void LargeDataToXML()
    {
        string table_schema = "geoip";
        string table_name = "geoip_blocks_temp";
    
        // table_schema = "public";
        // table_name = "t_sys_language_monthnames";
    
    
        System.Xml.XmlWriterSettings xs = new System.Xml.XmlWriterSettings();
        xs.Indent = true;
        xs.IndentChars = "    ";
        xs.NewLineChars = System.Environment.NewLine;
        xs.OmitXmlDeclaration = false; // // <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
        // xs.Encoding = System.Text.Encoding.UTF8; // doesn't work with pgsql 
        xs.Encoding = new System.Text.UTF8Encoding(false);
    
        string exportFilename = System.IO.Path.Combine(@"d:\", table_name + ".xml");
    
        using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(exportFilename, xs))
        {
            writer.WriteStartDocument();
            writer.WriteStartElement(table_name);
    
            writer.WriteAttributeString("xmlns", "xsi", null, System.Xml.Schema.XmlSchema.InstanceNamespace);
            // writer.WriteAttributeString("xsi", "schemaLocation", null, System.Xml.Schema.XmlSchema.InstanceNamespace);
    
    
    
            using (System.Data.Common.DbConnection con = Npgsql.NpgsqlFactory.Instance.CreateConnection())
            {
                con.ConnectionString = GetCS();
    
                using (System.Data.Common.DbCommand cmd = con.CreateCommand())
                {
                    cmd.CommandText = "SELECT * FROM " + table_schema + "." + table_name;
    
    
                    if (con.State != System.Data.ConnectionState.Open)
                        con.Open();
    
                    using (System.Data.Common.DbDataReader dr = cmd.ExecuteReader(System.Data.CommandBehavior.SequentialAccess))
                    {
    
                        if (dr.HasRows)
                        {
                            int fc = dr.FieldCount;
    
                            string[] columnNames = new string[fc];
                            // System.Type[] columnTypes = new System.Type[fc];
    
                            for (int i = 0; i < dr.FieldCount; ++i)
                            {
                                columnNames[i] = dr.GetName(i);
                                // columnTypes[i] = dr.GetFieldType(i);
                            } // Next i 
    
                            while (dr.Read())
                            {
                                // object[] thisRow = new object[dr.FieldCount];
    
                                writer.WriteStartElement("record");
    
                                for (int i = 0; i < fc; ++i)
                                {
                                    writer.WriteStartElement(columnNames[i]);
                                    object obj = dr.GetValue(i);
    
                                    if (obj != System.DBNull.Value)
                                    {
                                        writer.WriteValue(obj);
                                    }
                                    else
                                        writer.WriteAttributeString("xsi", "nil", System.Xml.Schema.XmlSchema.InstanceNamespace, "true");
    
                                    writer.WriteEndElement();
                                } // Next i
    
                                writer.WriteEndElement();
    
                            } // Whend 
    
                        } // End if (dr.HasRows) 
    
                    } // End Using dr 
    
                    if (con.State != System.Data.ConnectionState.Open)
                        con.Close();
                } // End Using cmd 
    
            } // End Using con 
    
            writer.WriteEndElement();
        } // ENd Using writer 
    
    } // End Sub LargeDataToXML 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-31
      相关资源
      最近更新 更多