Estou tentando fazer uma importação com o importador em massa do vBulletin. Consegui fazer com que ele funcionasse na maior parte. Ele criou usuários e posts, mas os tópicos não estão sendo criados.
O que está sendo passado para create_topics(topics) parece certo. O que está em processed em base.rb:create_records parece certo (skipped não está definido). Mas nenhum tópico está sendo criado.
Aqui está o erro:
ERROR: null value in column "pinned_globally" of relation "topics" violates not-null constraint
Mas se um tópico não está fixado globalmente, qual valor ele deve ter? Estou tentando comentar esse campo em TOPIC_COLUMNS em base.rb.
EDIT: Acho que isso pode resolver, mas não saberei por um tempo:
create_topics(topics) do |row|
created_at = Time.zone.at(row[5])
t = {
imported_id: row[0],
title: normalize_text(row[1]),
category_id: category_id_from_imported_id(row[2]),
user_id: user_id_from_imported_id(row[3]),
closed: row[4] == 0,
created_at: created_at,
views: row[6] || 0,
visible: row[7] == 1,
pinned_globally: row[8] == 1 # ============== JP adicionou isso:
}
t[:pinned_at] = created_at if row[8] == 1
t
end
Aha. Isso explica por que não está no código, eu acho.
Mas isso não resolve o mistério.
pinned_globally | boolean | | not null | false
EDIT:
IA Aleatória diz:
Talvez isso seja uma “ferramenta de inserção em massa”?
Não consigo encontrar uma fonte que diga credivelmente o que a citação acima diz, mas faz sentido, no sentido de que o objetivo é ser rápido, então pular padrões parece algo que faria, e explica o que está acontecendo e, espero, a solução que ainda estou esperando para ver se funcionou.
Se uma lista de colunas for especificada, COPY TO copia apenas os dados nas colunas especificadas para o arquivo. Para COPY FROM, cada campo no arquivo é inserido, em ordem, na coluna especificada. Colunas da tabela não especificadas na lista de colunas COPY FROM receberão seus valores padrão.
Então, se eu estiver lendo isso corretamente, se um campo estiver na lista de campos, o postgres copia cegamente o que você dá a ele, e em branco/nulo é inserido em vez do padrão desejado.
Está ficando cada vez mais lento. Há alguma razão para não usar LIMIT 1000 como o importador regular faz? Parece que talvez 885K tópicos seja muito para morder de uma vez?
Verifiquei o script para a última importação em massa que fiz e ele realmente tem um pinned_globally: false explícito, então isso é aparentemente necessário - é o único valor de coluna explícito codificado no código.
create_topics(topics) do |row|
t = {
imported_id: row[0],
title: my_normalize_text(row[1]),
category_id: category_id_from_imported_id(row[2]),
user_id: user_id_from_imported_id(row[3]),
created_at: Time.zone.at(row[4]),
pinned_globally: false
}
Estranho, já que não tem isso para outras colunas semelhantes de not null, default false como closed ou has_summary.
A última importação que fiz com o importador em massa fez mais de 3 milhões de tópicos em cerca de 2 horas. Talvez você tenha um vazamento de memória? Ou talvez seu código MySQL (ou o que quer que você use para ler os dados de origem) esteja lento em algum lugar?
Boas notícias! Todos os tópicos foram criados! Más notícias! Nenhum dos posts está conectado a eles, mas espero que seja porque os posts foram criados antes dos tópicos.
Isso é estranho. Tinha tanta certeza de que tinha uma explicação.
Os 7 milhões de posts levaram apenas algumas horas, mas os menos de 1 milhão de tópicos levaram cerca de 4.
É uma máquina antiga (que aparentemente compraram apenas para o trabalho?), e o mysql é remoto. Olhando para o htop, não há vazamento de memória óbvio no nível do sistema. Limpei todos os dados e estou reconstruindo os contêineres para ver se funcionará desta vez.