2010-02-28 5 views
5

Ich möchte die Objektdatenbank verwenden, um einige in IronPython erstellte Klassen beizubehalten. Die Datenbank ist db4o für .NET 2.0 (heute heruntergeladen). Der Code sieht wie folgt aus:Wie Objekte, die in IronPython erstellt wurden, in Objektdatenbanken gespeichert werden

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) 

I Ausnahme bei 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 '$' 

Ich vermute bekommen, dass das Problem mit Ironpython und seiner Art System ist, weil die Klasse Person nicht Standard .NET-Klasse ist. Ich habe versucht, System.IO.FileInfo persistieren und es hat gut funktioniert. Wie kann ich ein Objekt speichern, das eine Instanz einer Klasse in IronPython ist?

+0

Können Sie dieses Problem mit nur Python replizieren, ein nicht Eisen Python. –

+0

Ich weiß nicht, wie man .NET-Assemblies nach Python importiert (ich dachte, das ist nicht möglich). Also kann ich das mit meinem derzeitigen Wissen nicht replizieren. – stej

+0

Wahrscheinlich nicht, was Sie hören möchten, aber Sie könnten Ihre Modelle in C# definieren und sie in Ihre IronPython-Umgebung importieren. Ich werde gerne wissen, wie Sie das Problem lösen, wenn überhaupt. – tarn

Antwort

2

Db4o verwendet die CLR-Reflection-Mechanismen, um Metainformationen der Objekte abzurufen, um sie zu speichern. Dies funktioniert gut für C#, VB.NET usw. Sprachen wie IronPython und IronRuby haben eine zusätzliche Ebene über der CLR verwendet, um all die wundervollen dynamischen Funktionen zu ermöglichen.

Jetzt, wenn db4o die CLR-Reflektion verwendet, werden die zusätzlichen Elemente hinzugefügt, mit denen die dynamischen Features implementiert werden. In dem Versuch, diese Informationen zu speichern, schlägt fehl. Es ist kein einfaches eine elegante Lösung verfügbar heute = (

  1. Wie bereits in den Kommentaren erwähnt, könnten Sie Sie Daten-Objekt in C# oder VB.NET definieren, so dass Sie nur alte CLR-Objekte haben. Ich denke, das Lösung ist die schnellste und sollte funktionieren.
  2. Sie durch Schreiben Sie besitzen reflector db4o über das Objekt-Modell von python. Aber das ist sicherlich nicht einfach.
  3. db4o hat eine ‚SelfReflector‘, die für Umgebungen ‚lehren‘ könnte gedacht ohne Reflektion.Im Prinzip fügen Sie manuell die erforderlichen Meta-Informationen für jedes Objekt hinzu, aber ich kann keine Dokumentation dazu finden.

Eine andere Möglichkeit wäre, ein ODBMS zu verwenden, das speziell für Python erstellt wurde, wie ZODB anstelle von db4o. Aber ich bin mir nicht sicher, ob ZOBR auf IronPython läuft.

+0

Vielen Dank für Ihre Antwort, es hilft mir sehr, auch wenn es negativ ist. Ich schaue mir # 2 und # 3 nur zum Spaß an (wenn ich es wirklich brauchte, würde ich es wie in # 1 machen). – stej

-1

Sie Gurke verwenden könnten die Instanzen bestehen bleiben:

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

und dann cPickle.loads verwenden (...), um das Objekt zu bringen zurück.

+0

Das ist keine gute Idee. Es ist nahezu nutzlos, serialisierte Objekte in db4o zu speichern, da Sie fast alle Funktionen, die db4o bietet, wie Abfragen, Aktualisierungen usw. verlieren. – Gamlor

+0

Zustimmen. Ich möchte Funktionen von Objektdatenbanken verwenden, was nicht möglich wäre. – stej

Verwandte Themen