首页 > 解决方案 > 如何从 python 中不同服务器的数据库中正确获取对象?

问题描述

我正在尝试使用 django 使用机器学习和 Web 服务器,并且我的 Web 和机器学习服务器都使用相同的 dockerized postgres 数据库。机器学习服务器创建机器学习模型并使用 pickle 将它们写入数据库。我在机器学习服务器中有一个 Regressor 类,如下所示:

class Regressor:
    def __init__(self):
        self.predictions = []
        self.yTrue = []
        self.predDiffs = []
        self.model = object
        self.name = ""
        #some methods below

我有一个类可以为 orm 技术创建一个适当的数据库表

class RegressorTable(DeclarativeBase):
    __tablename__ = "ml_models"

    id = Column(Integer, primary_key=True)
    regressorName = Column(String)
    regressorModel = Column(LargeBinary)

在机器学习和 django web 服务器中,我有 2 个函数可以将模型转换为二进制和二进制到模型

def modelToBinary(model):
    return pickle.dumps(model)


def binaryToModel(data):
    return pickle.loads(data)

这是我在机器学习服务器中为数据库保存回归模型的方法:

def saveModelsToDb(predictorArray):
    for predictor in predictorArray:
        predictorForTable = RegressorTable()
        predictorForTable.regressorName = predictor.name
        predictorForTable.regressorModel = modelToBinary(predictor)
        DBSession.add(predictorForTable)
        DBSession.commit()

上述代码中的 predictorArray 包含 Regressor 对象。当我尝试在机器学习服务器中保存和加载模型时,我可以成功保存、加载和使用我的回归器对象。我有一个网络服务器,这是我的模型:

class RegressorTable(models.Model):
    regressorName = models.CharField(max_length=50)
    regressorModel = models.BinaryField()
    
    class Meta:
        db_table = "ml_models"

在views.py 中,我有上面提到的modelToBinary 和binaryToModel 方法。我有这样的代码:

def getPredictions(request):
    predictorArray = RegressorTable.objects.filter()
    finalPrediction = finalDecision(predictorArray, np.array([20]).reshape(-1, 1))
    context = {"prediction": finalPrediction}
    return render(request, "get_predictions.html", context=context)

我可以在机器学习服务器中成功保存、加载和使用回归器对象。在机器学习服务器中,我保存了 Regressor 对象,我想在我的 django Web 服务器中使用它们。当我尝试使用上面的代码获取它们时,它会引发异常

Can't get attribute 'Regressor' on <module '__main__'>

如何在我的 django Web 服务器中正确加载已由机器学习服务器从数据库中保存到数据库的回归器对象?

标签: pythondjangodatabase

解决方案


两个应用程序中的模块和类名称需要相同,因为pickle使用名称来确定如何恢复类实例。

基于on <module '__main__'>,您的 Regressor 类是在执行的主模块中定义的,而 Django 绝不会发生这种情况。

在 eg 中定义类regressor.py(或者更好的是,两个应用程序中的同一个包在my_ml_library/regressor.py哪里my_ml_library) - 并且还要记住这pickle不会保存函数定义,因此如果您进行可能与旧数据不兼容的代码更改,您会需要重新训练你的模型。


推荐阅读