数据库
首页 > 数据库> > python – SQLAlchemy:知道模型对象的字段名称和值?

python – SQLAlchemy:知道模型对象的字段名称和值?

作者:互联网

我正在尝试保持SOLID面向对象的编程原则,保持DRY等,但我对Python / SQLAlchemy / Pyramid的新见感正在变得非常困难.

我正在尝试将我现在所知道的SQLAlchemy模型用于创建一个简单的Pyramid Framework对象并使用我所知道的C#中的“反射”,它可能在Python中被称为不同的东西(Introspection?不确定为这只是我在python的第二周,但我在其他语言(C/C++ / C#,Java等)方面有很多经验,所以麻烦似乎是将我的知识映射到python的词汇表,抱歉),找出数据库表的字段名,最重要的是当前字段值,当我不知道列名或事先形状的任何形状时.

那就对了;我不知道’derp’实例有一个名为id或name的字段,只是它有每个列中的列和值.这就是我所关心的.

目标是能够采用任何SQLAlchemy定义的数据模型,并将其转换为column_name的字典 – >在JSON中找到的那种简单数据类型的column_value字段,因为我想最终将我在SQLAlchemy中创建的任何对象序列化为json对象,但是只要字典包含正确的类型,我将从那里解决它的简单问题数据的.手动对每个对象执行此操作违反了太多良好的清洁代码规则,并且会随着时间的推移创建太多的工作;我可以花一个星期的时间在这上面,并以正确的方式做到这一点,从而节省时间和精力.

所以如果我在SQLAlchemy中定义了一个类:

class SimpleFooModel(Base):
    id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
    name = Column(VARCHAR(length=12), nullable=False, index=True)

..我有一个等于(在python中)的实例:

derp = SimpleFooModel(id=7, name="Foobar")

我希望能够只拥有上面描述的’derp’实例变量,并且不知道模型的形状,并且能够将其展平为该简单对象的python key->值字典,其中可以使用python syslib中的import json将该字典中的每个值序列化为JSON.

问题是,我已经连续两天看了这个,我无法找到一个答案,可以在我的单元测试中得到我想要的结果任何地方;谷歌一直把我带到这里的老帖子,关于那些使用不再适用的接口的图书馆的旧版本,或者已经接受了根本不起作用的答案;并且由于它们中没有一个是最近令我感到惊讶的(但是为什么Stack Overflow在他们错误时保留它们并允许谷歌误导人们确实让我感到惊讶)

我知道我可以为每个对象手动连接每个对象到json等,但这不仅不优雅,效率低,因为它只是为我创造了更多的工作,因为我创建了更多的对象,并可能导致路上的大错误.我想知道如何以正确的方式做到这一点,有内省/反思,但似乎没有人知道,并且声称在堆栈溢出的所有给出示例的人实际上根本不起作用(至少对于当前事物的版本)

这对我来说似乎是一个非常常见的用例;并获取列字段列表,然后使用getattr迭代它 – 就像许多答案所说的那样 – 也不能按预期工作;它只是创建看起来像永远不会返回列的实际值的名称空间,并且实际上不存在于任何代码中,因为sqlalchmy创建的字段都不是singleton / static.

所以:

    from sqlalchemy.inspection import inspect

    obj = inspect(derp, raiseerr=True)

    for key in obj.attrs.keys():
        fields[key] = getattr(derp, key)
        print fields[key]

只是给我:

    [Class Name].[Column Name]

..或者在这种情况下只是给了我:

    SimpleFooModel.id
    SimpleFooModel.name

对于id和name,分别不是7和“Foobar”的值,这是我在测试中实际预期的.

事实上,似乎我甚至无法找到WHERE值存储在对象模型中;或者我可以强行解决这个问题,让他们从那里作为一个丑陋的,邪恶的黑客,我会羞于看.我通过“官方公共API”获得的很多对象似乎都不知道存储真实数据的位置,但很高兴地告诉我列名称和类型,限制等所使用的路径的名称……不是我想要的实际数据.

然而,由于我的要求是我不提前知道字段名称,使用derp.id或derp.name调用来收集值不是一个选项,因为这会违反SOLID并强迫我为每个类重复工作.所以它不是一个选择.

也许它是我在2天内没有睡觉的事实,但我真的很难在这些书中看不出这是一个严重的设计缺陷;我只想将表示表中单行的SQLAlchemy定义的Model对象序列化为python字典而不必事先知道字段的名称,而且许多其他语言使这变得容易或甚至是微不足道的,这似乎是远远的太难了.

有人可以解释一个工作的解决方案或为什么我错了想将SOLID应用于我的代码?

编辑:更新拼写.

解决方法:

使用以下类扩展您的模型:

class BaseModel(object):

    @classmethod
    def _get_keys(cls):
        return sa.orm.class_mapper(cls).c.keys()

    def get_dict(self):
        d = {}
        for k in self._get_keys():
            d[k] = getattr(self, k)
        return d

这将完全符合您的要求,以{‘column_name’:’value’}对的形式返回一个字典.

标签:json,python,solid-principles,sqlalchemy,pyramid
来源: https://codeday.me/bug/20190624/1280770.html