2010-02-28 64 views
5

Me gustaría utilizar la base de datos de objetos para conservar algunas clases creadas en IronPython. La base de datos es db4o para .NET 2.0 (descargado hoy). El código es el siguiente:Cómo almacenar objetos creados en IronPython para bases de datos de objetos

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) 

llego a excepción 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 '$' 

Sospecho que el problema es con IronPython y su sistema de tipos, porque la clase no es Person clase de .NET estándar. Traté de persistir System.IO.FileInfo y funcionó bien. ¿Cómo puedo almacenar un objeto que sea instancia de una clase en IronPython?

+0

Puede replicar este problema usando solo python, una python no de hierro. –

+0

No sé cómo importar ensamblados .NET a python (pensé que no era posible). Entonces, no puedo replicar eso con mi conocimiento actual. – stej

+0

Probablemente no sea lo que quiere escuchar, pero podría definir sus modelos en C# e importarlos a su entorno IronPython. Me gustaría saber cómo terminas resolviendo esto, si es que lo haces. – tarn

Respuesta

2

Db4o utiliza los mecanismos de reflexión CLR para recuperar la metainformación de los objetos, con el fin de almacenarla. Esto funciona bien para C#, VB.NET, etc. Los lenguajes como IronPython e IronRuby usaron una capa adicional en la parte superior del CLR para permitir todas las maravillosas características dinámicas.

Ahora cuando db4o utiliza el CLR-reflection se ve agregar las cosas adicionales que se utilizan para implementar las características dinámicas. En el intento de almacenar esta información, falla. No un simple una solución elegante disponibles hoy en día = (

  1. Como ya se ha dicho en los comentarios, que se podría definir de datos a objetos en C# o VB.NET, quedando con viejos objetos CLR llanos. Creo que esto es la solución más rápida y debería funcionar.
  2. se puede 'enseñar' db4o sobre el objeto-modelo de pitón escribiendo es el propietario reflector. Pero eso no es ciertamente fácil.
  3. db4o tiene un 'SelfReflector' que está destinado a entornos sin reflexión. Básicamente, se agrega manualmente la metainformación requerida para cada objeto. Sin embargo, no puedo encontrar ninguna documentación al respecto.

Otra posibilidad sería utilizar un ODBMS que se crea especialmente para Python, como ZODB en lugar de db4o. Pero no estoy seguro de si ZOBR se ejecuta en IronPython.

+0

Gracias por su respuesta, me ayuda mucho, incluso cuando es negativo. Echaré un vistazo a los números 2 y 3, solo por diversión (si realmente lo necesitara, lo haría como en el n. ° 1). – stej

-1

Usted podría utilizar salmuera para persistir los casos:

cPickle importación db.Store (cPickle.dumps (P1))

y luego usar cPickle.loads (...) para llevar el objeto espalda.

+0

No es una buena idea. Es casi inútil almacenar objetos serializados en db4o, porque pierde casi todas las características que ofrece db4o, como consultas, actualizaciones, etc. – Gamlor

+0

De acuerdo. Quiero usar características de las bases de datos de objetos, lo que no sería posible. – stej

Cuestiones relacionadas