2014-11-24 3 views
3

Я делаю объемные вставки 10000 записей в Postgres:PostgreSQL эквивалент MySQL --force флаг

INSERT INTO TABLE VALUES (v1),...,(v10000) 

Я делаю это с помощью библиотеки Python psycopg2. В настоящее время, если один из кортежей, скажем, 5000 бомб (например, если поле имеет неправильный тип), вся моя вставка пакета не работает, потому что генерируется исключение. Я ищу эквивалент флага MySQLsforfor, который решает именно эту проблему; который говорит MySQL, чтобы продолжать идти на какие-либо ошибки (http://dev.mysql.com/doc/refman/5.0/en/mysql-command-options.html#option_mysql_force)

Я не вижу здесь ничего, и это для еще более новой ПГ, который является весьма тревожным: http://www.postgresql.org/docs/9.3/static/sql-select.html

+0

На что он бомбит? –

+0

Например, значение X слишком велико для «smallint». Я просто хочу не вставлять все строки, которые нарушают некоторую ошибку вставки данных и продолжают идти. Поскольку я до сих пор не знаю всех возможных ошибок данных, я бы скорее не реализовал эту логику, чтобы проверять кортежи, прежде чем пытаться вставить ... какой кошмар был бы. – Tommy

+0

Я не думаю, что это возможно. Обработка транзакций Postgres более строгая, чем MySQL. Postgres не поддерживает транзакции, в которых могут выполняться только некоторые из операторов, поскольку это нарушает «атомную» концепцию транзакции. Единственный способ сделать это можно с помощью отдельных вставок с точками сохранения для каждой вставки. Но это будет очень медленно. –

ответ

0

сделать это в PSQL \set ON_ERROR_ROLLBACK on и попробовать он снова

+0

Выполнять ли это это как часть транзакции? Я взаимодействую с Psycopg2, как упоминалось, а не с собственным CLI CLI. – Tommy

+0

Насколько я знаю, это можно сделать только с помощью psql-клиента. – bhowden

+1

Да, тогда это не помогает. Разве что-то, как я могу установить эту вещь навсегда. – Tommy

1

Скажите psycopg, что вы хотите использовать уровень изоляции транзакции «autocommit», то есть он не будет открывать транзакцию для вас, и каждый оператор будет автоматически зафиксирован. Обратите внимание, что вам придется перехватывать исключения и игнорировать (или лучше их записывать). Пример:

import psycopg2 
import psycopg2.extensions 

conn = psycopg2.connect("...") 
conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT) 
curs = conn.cursor() 

for row in your_data: 
    try: 
     curs.execute("INSERT INTO table VALUES (%s, %s, ...)", row) 
    except Exception, err: 
     print err 

# no need to commit! 
+0

Объемная вставка является частью транзакции, которая должна быть отброшена, если что-то еще в транзакции завершится с ошибкой; это влияет на это? – Tommy

+0

Определенно. Извините, вы не можете сделать «автокоммит» * внутри * транзакции. Если бы я был вами, я бы просто переупорядочил SQL: заполнить массивную таблицу с помощью autocommit; запустите транзакцию, и если она не удалась, просто удалите строки/отбросьте массивную таблицу. – fog

Смежные вопросы