2

我正在尝试将表从一个数据库复制到另一个数据库(不是模式)。我在终端中使用的代码如下:

pg_dump -U postgres -t OldSchema.TableToCopy OldDatabase | psql -U postgres -d NewDatabase

当我按 Enter 时,它请求 postgres 密码我输入我的通行证,然后它请求 psql 密码。我输入它并按 Enter。我收到很多:

invalid command \N
ERROR: relation "TableToCopy" does not exist

两个表都有UTF8编码。难道我做错了什么?
操作系统:Windows XP

错误输出:

psql:TblToCopy.sql:39236: invalid command \N
psql:TblToCopy.sql:39237: invalid command \N
psql:TblToCopy.sql:39238: invalid command \N
.
.
.

在上面的数百个错误之后,终端回显:

psql:TblToCopy.sql:39245: ERROR: syntax error at or near "509"
LINE 1: 509 some gibberish words and letters here

最后:

sql:TblToCopy.sql:39245: ERROR: relation "TableToCopy" does not exist

编辑 我用 psql 阅读了对相同问题\N 错误的回复,它说使用 INSERT 而不是 COPY,但在文件 pg_dump 中创建了 COPY。如何对 pg_dump 说使用 INSERT 而不是 COPY?


我将带有 iconv 的文件转换为 utf-8。现在该错误已经消失,但我有一个新错误。在这种特殊情况下,当我使用 psql 将数据导入数据库时​​,会发生一些新的事情。表已创建但没有数据。它说:

SET
SET
SET
SET
SET
SET
SET
SET
CREATE TABLE
ALTER TABLE
psql:tblNew.sql:39610: ERROR:  value too long for type character(3)
CONTEXT:  COPY words, line 1, column first_two_letters: "سر"
ALTER TABLE
ALTER TABLE
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE TRIGGER
4

2 回答 2

2

表名应加引号,如下

pg_dump -U postgres -t OldSchema."TableToCopy" OldDatabase | psql -U postgres -d NewDatabase

我建议你分两步完成这项工作

步骤1

pg_dump -U postgres -t OldSchema."TableToCopy" OldDatabase > Table.sql

如果第 1 步顺利,则执行第 2 步。

第2步

psql -U postgres -d NewDatabase -f Table.sql
于 2013-12-26T05:39:19.177 回答
2

我尝试使用 Encoding: UTF8 和表创建一个数据库,并插入 COPY 命令尝试插入的两个 UTF-8 编码字符,并且在使用 INSERT 时它可以工作。

CREATE DATABASE test
  WITH OWNER = postgres
       ENCODING = 'UTF8'
       TABLESPACE = pg_default
       LC_COLLATE = 'English_United States.1252'
       LC_CTYPE = 'English_United States.1252'
       CONNECTION LIMIT = -1;

CREATE TABLE x
(
  first_two_letters character(3)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE x
  OWNER TO postgres;

INSERT INTO x(
            first_two_letters)
    VALUES ('سر');

根据http://rishida.net/tools/conversion/对于失败的 COPY Unicode 代码点是:

U+0633 U+0631

这是两个字符,这意味着您应该能够将它们存储在定义为 character(3) 的列中,该列存储长度最多为 3 个字符(而不是字节)的字符串。

如果我们尝试插入,它会成功:

 INSERT INTO x( 
                first_two_letters) 
        VALUES (U&'\0633\0631');

pgdump 文档中,您可以使用 --inserts 选项插入而不是复制

--inserts 将数据转储为 INSERT 命令(而不是 COPY)。这将使恢复非常缓慢;它主要用于制作可以加载到非 PostgreSQL 数据库的转储。但是,由于此选项为每一行生成一个单独的命令,因此重新加载行时的错误只会导致该行丢失,而不是整个表内容。请注意,如果您重新排列了列顺序,还原可能会完全失败。--column-inserts 选项对列顺序更改是安全的,尽管速度更慢。

尝试将其用于第 1 步:

pg_dump -U postgres -t OldSchema."TableToCopy" --inserts OldDatabase > Table.sql

我还尝试从表复制到文件并使用复制导入,对我来说它有效。

您确定您的客户端和服务器数据库编码是 UTF8 吗?

首先,将数据库“test”上的模式“public”中名为“x”的表导出到纯文本 SQL 文件:

pg_dump -U postgres -t public."x" test > x.sql

它创建了 x.sql 文件,其中包含:

--
-- PostgreSQL database dump
--
SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;

SET search_path = public, pg_catalog;

SET default_tablespace = '';

SET default_with_oids = false;

--
-- Name: x; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
--

CREATE TABLE x (
    first_two_letters character(3)
);


ALTER TABLE public.x OWNER TO postgres;

--
-- Data for Name: x; Type: TABLE DATA; Schema: public; Owner: postgres
--

COPY x (first_two_letters) FROM stdin;
سر 
\.


--
-- PostgreSQL database dump complete
--

其次,导入:
psql -U postgres -d test -f x.sql

于 2013-12-26T09:33:05.270 回答