Pergunta

Eu tenho um problema simples no SQLAlchemy. Eu tenho um modelo em uma tabela, vamos chamá-lo Model1 aqui. Eu quero adicionar uma linha nesta tabela, e obter a chave autoincremented, para que eu possa criar um outro modelo com ele, e usar essa chave. Este não é um projeto de banco de dados falhos (1: 1 relação etc). Eu simplesmente precisa esta chave em outra tabela, porque a outra tabela está sendo transferido para um host remoto, e eu preciso as chaves correspondentes para que os servidores irão entender um ao outro. Não haverá nenhuma outra referência local entre estas 2 tabelas, e também não é possível criar relações por causa disso.

Considere o seguinte código:

object1 = model.Model1(param)
DBSession.add(object1)

# if I do this, the line below fails with an UnboundExecutionError.
# and if I dont do this, object1.id won't be set yet
#transaction.commit()

object2 = model.AnotherModel(object1.id) #id holds the primary, autoincremented key

Eu queria nem sequer tem de se comprometer "manualmente". Basicamente o que eu gostaria de conseguir é, "Model1" está em constante crescimento, com o aumento da Model.id chave primária. AnotherModel é sempre apenas um pouco fração de Model1, que ainda não foi processado. Claro que eu poderia adicionar um sinalizador em "Model1", um campo boolean na tabela para marcar elementos já processados, mas eu estava esperando que isso não seria necessário.

Como posso obter o meu trabalho código acima?

cumprimenta,

Tom

Foi útil?

Solução

Um par de coisas:

  • Você poderia explicar o que o transaction variável é obrigado a?
  • Exatamente o que declaração levanta a UnboundExecutionError?
  • Por favor, forneça a mensagem de exceção completo, incluindo rastreamento de pilha.
  • A coisa 'normal' para fazer neste caso, seria DBSession.flush() chamada. Você já tentou isso?

Exemplo:

object1 = Model1(param)
DBSession.add(object1)
DBSession.flush()
assert object1.id != None # flushing the session populates the id

object2 = AnotherModel(object1.id)

Para uma grande explicação para a sessão SA eo que flush() faz, consulte Usando sessão.

Basicamente, flush() provoca casos pendentes para tornar-se persistente - o que significa que novos objetos são inseridos no banco de dados tabelas. flush() também atualiza as tabelas com valores para instâncias que as faixas de sessão que tem alterações.

commit() sempre questões flush() primeiro.

Dentro de uma transação, você pode lavar várias vezes. Cada descarga () provoca UPDATEs e / ou inserções na base de dados. Toda a transação pode ser comprometida ou revertida.

Outras dicas

Se você deseja obter novos identificadores de chave primária para gerar sem que nada seja comprometida, basta ligar Session.flush (). Que irá emitir tudo pendente para o banco de dados dentro da transação corrente.

Eu só usei isso com ForeignKeys, para que, no segundo caso, em vez faria model.AnotherModel (model1 = object1), e então ele só trabalhou (tm). Então, eu suspeito que isso pode ser um problema com os seus modelos, então talvez você poderia publicá-las também?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top