Domanda

Mi piacerebbe usare oggetto di database a persistere alcune classi create in IronPython. Il database è db4o for .NET 2.0 (oggi scaricato). Il codice è simile al seguente:

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)

ottengo un'eccezione a 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 '$'

Ho il sospetto che il problema è con IronPython e il suo sistema di tipo, perché la classe non è Person classe standard NET. Ho provato a persistere System.IO.FileInfo e ha funzionato bene. Come posso conservare un oggetto che è un'istanza di una classe in IronPython?

È stato utile?

Soluzione

db4o utilizza i meccanismi CLR-riflessione per recuperare le meta-informazioni degli oggetti, al fine di conservarlo. Questo funziona bene per C #, VB.NET ecc Linguaggi come IronPython e IronRuby utilizzato uno strato aggiuntivo in cima al CLR per consentire tutte le meravigliose caratteristiche dinamiche.

Ora, quando db4o utilizza il CLR-riflessione è vede aggiungere il materiale aggiuntivo che viene utilizzato per implementare le caratteristiche dinamiche. Nel tentativo di archiviare queste informazioni è fallisce. Ci Non un semplice una soluzione elegante disponibile oggi = (

  1. Come già indicato nei commenti, è possibile definire i tuoi dati-oggetto in C # o VB.NET, in modo da avere gli oggetti CLR vecchi pianura. Penso che questa sia la soluzione più rapida e dovrebbe funzionare.
  2. Si potrebbe 'insegnare' db4o circa l'oggetto-modello del pitone scrivendo si possiede riflettore . Ma non è certo facile.
  3. db4o ha un 'SelfReflector' che è destinato ad ambienti senza riflessione. Fondamentalmente ci aggiungere manualmente il meta-informazioni necessarie per ogni oggetto. Tuttavia non riesco a trovare alcuna documentazione su questo.

Un'altra possibilità sarebbe quella di utilizzare un ODBMS che viene creato appositamente per Python, come ZODB anziché db4o . Ma io non sono sicuro se ZOBR gira su IronPython.

Altri suggerimenti

Si potrebbe utilizzare salamoia a persistere le istanze:

cPickle import db.Store (cPickle.dumps (p1))

e quindi utilizzare cPickle.loads (...) per portare l'oggetto indietro.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top