У меня есть десятки миллионов строк для переноса из массивов многомерных массивов в базу данных PostgreSQL. Мои инструменты - Python и psycopg2. Самый эффективный способ массовой загрузки данных - copy_from
. Однако мои данные - это в основном 32-битные числа с плавающей запятой (real или float4), поэтому я бы предпочел не конвертировать из реального → text → real. Вот пример базы данных DDL:
CREATE TABLE num_data
(
id serial PRIMARY KEY NOT NULL,
node integer NOT NULL,
ts smallint NOT NULL,
val1 real,
val2 double precision
);
Вот где я нахожусь с Python, используя строки (текст):
# Just one row of data
num_row = [23253, 342, -15.336734, 2494627.949375]
import psycopg2
# Python3:
from io import StringIO
# Python2, use: from cStringIO import StringIO
conn = psycopg2.connect("dbname=mydb user=postgres")
curs = conn.cursor()
# Convert floating point numbers to text, write to COPY input
cpy = StringIO()
cpy.write('\t'.join([repr(x) for x in num_row]) + '\n')
# Insert data; database converts text back to floating point numbers
cpy.seek(0)
curs.copy_from(cpy, 'num_data', columns=('node', 'ts', 'val1', 'val2'))
conn.commit()
Есть ли эквивалент, который может работать с использованием двоичного режима? I.e, сохранить числа с плавающей запятой в двоичном формате? Это не только сохранит точность с плавающей точкой, но может быть и быстрее.
(Примечание: чтобы увидеть ту же точность, что и в примере, используйте SET extra_float_digits='2'
)