Как хранить объекты, созданные в IronPython, в объектных базах - PullRequest
5 голосов
/ 01 марта 2010

Я бы хотел использовать объектную базу данных для сохранения некоторых классов, созданных в IronPython. База данных db4o для .NET 2.0 (скачано сегодня). Код выглядит так:

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)

Я получаю исключение на 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 '$'

Я подозреваю, что проблема в IronPython и его системе типов, потому что класс Person не является стандартным классом .NET. Я пытался сохранить System.IO.FileInfo, и это сработало хорошо. Как я могу сохранить объект, который является экземпляром класса в IronPython?

Ответы [ 2 ]

2 голосов
/ 08 марта 2010

Db4o использует механизмы отражения CLR для извлечения метаинформации объектов для ее хранения. Это прекрасно работает для C #, VB.NET и т. Д. Такие языки, как IronPython и IronRuby, использовали дополнительный слой поверх CLR, чтобы обеспечить все замечательные функции динамики.

Теперь, когда db4o использует CLR-отражение, добавьте дополнительные элементы, которые используются для реализации динамических функций. При попытке сохранить эту информацию не удается. Сегодня не существует простого элегантного решения = (

  1. Как уже говорилось в комментариях, вы можете определить свой объект данных в C # или VB.NET, чтобы у вас были простые старые объекты CLR. Я думаю, что это самое быстрое решение, и оно должно работать.
  2. Вы можете «научить» db4o объектной модели python, написав свой собственный отражатель . Но это, конечно, нелегко.
  3. Db4o имеет «SelfReflector», который предназначен для сред без отражений. Там в основном вручную добавляют необходимую мета-информацию для каждого объекта. Однако я не могу найти документацию по этому вопросу.

Другой возможностью было бы использование ODBMS, созданной специально для Python, например ZODB вместо db4o. Но я не уверен, что ZOBR работает на IronPython.

0 голосов
/ 01 марта 2010

Вы можете использовать pickle для сохранения экземпляров:

импорт cPickle db.Store (cPickle.dumps (p1))

и затем используйте cPickle.loads (...), чтобы вернуть объект.

...