Pergunta

Eu gostaria de usar o banco de dados de objetos para persistir algumas classes criadas no IronPython. O banco de dados é DB4O para .NET 2.0 (baixado hoje). O código se parece com o seguinte:

import clr
clr.AddReferenceToFileAndPath(r"C:\dev\Db4objects\db4o-7.12-net20\bin\net-2.0\Db4objects.Db4o.dll")
from Db4objects.Db4o import *
db = Db4oFactory.OpenFile(r'G:\IronPython\test\db4o\database.db')

class Person(object):  
  def __init__(self, name, age):
    self.Name = name
    self.Age = age

  def __str__(self):
    return 'Person: ' + self.Name + ' ' + str(self.Age)

p1 = Person('testp', 34)
db.Store(p1)

Eu recebo exceção em db.Store(p1)

Unexpected char '$'
ThrowUncheckedException at offset 4 in file:line:column <filename unknown>:0:0
FatalShutdown at offset 136 in file:line:column <filename unknown>:0:0
AsTopLevelCall at offset 112 in file:line:column <filename unknown>:0:0
AsTopLevelStore at offset 34 in file:line:column <filename unknown>:0:0
StoreInternal at offset 69 in file:line:column <filename unknown>:0:0
Store at offset 66 in file:line:column <filename unknown>:0:0
Store at offset 12 in file:line:column <filename unknown>:0:0
Store at offset 15 in file:line:column <filename unknown>:0:0
   v Microsoft.Scripting.Actions.Calls.MethodCandidate.Caller.CallWithInstance(Object[] args, Boolean& shouldOptimize)
   v IronPython.Runtime.Types.BuiltinFunction.BuiltinMethodCaller`2.Call1(CallSite site, CodeContext context, TFuncType
func, T0 arg0)
   v System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)
   v Microsoft.Scripting.Interpreter.DynamicInstruction`4.Run(InterpretedFrame frame)
   v Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
   v Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet](T0 arg0, T1 arg1)
   v IronPython.Compiler.PythonScriptCode.RunWorker(CodeContext ctx)
   v IronPython.Compiler.PythonScriptCode.Run(Scope scope)
   v IronPython.Hosting.PythonCommandLine.<>c__DisplayClass1.<RunOneInteraction>b__0()
Exception: Unexpected char '$'
CLR Exception:
    Exception
:
Unexpected char '$'

Eu suspeito que o problema esteja com o IronPython e seu sistema de tipos, porque a classe Person não é a classe .NET padrão. Eu tentei persistir System.IO.FileInfo E funcionou bem. Como posso armazenar um objeto que é uma instância de uma classe no IronPython?

Foi útil?

Solução

O DB4O usa os mecanismos de reflexão CLR para recuperar a meta-informação dos objetos, a fim de armazená-lo. Isso funciona bem para C#, vb.net etc. idiomas como IronPython e IronRuby usaram uma camada adicional no topo do CLR para permitir todos os maravilhosos recursos de dinâmica.

Agora, quando o DB4O usa, a reflexão CLR é vê, adicione o material adicional usado para implementar os recursos dinâmicos. Na tentativa de armazenar essas informações, falha. Não há uma solução simples e elegante disponível hoje = (

  1. Como já foi dito nos comentários, você pode definir seu objeto de dados em C# ou vb.net, para ter objetos antigos e antigos. Eu acho que esta é a solução mais rápida e deve funcionar.
  2. Você poderia 'ensinar' db4o sobre o modelo de objeto de Python escrevendo refletor. Mas isso certamente não é fácil.
  3. O DB4O possui um 'selfrefletor' destinado a ambientes sem reflexão. Basicamente, adicione manualmente o meta-info necessário para cada objeto. No entanto, não consigo encontrar nenhuma documentação sobre isso.

Outra possibilidade seria usar um ODBMS criado especialmente para Python, como Zodb em vez de db4o. Mas não tenho certeza se o Zobr corre no Ironpython.

Outras dicas

Você pode usar picles para persistir as instâncias:

importar cpickle db.store (cpickle.dumps (p1))

e use cpickle.loads (...) para trazer o objeto de volta.

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