具有mix的自定义类型的AttributeError

2024-04-20 05:09:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我在Python的klenmixer库中遇到了一个非常有趣的bug。在

https://github.com/klen/mixer

每当您尝试使用sqlalchemy.dialect.postgresql.INET。尝试将一个模型与此混合将带来以下跟踪。。。在

mixer: ERROR: Traceback (most recent call last):
File "/home/cllamach/PythonProjects/mixer/mixer/main.py", line 612, in blend
return type_mixer.blend(**values)
File "/home/cllamach/PythonProjects/mixer/mixer/main.py", line 130, in blend
for name, value in defaults.items()
File "/home/cllamach/PythonProjects/mixer/mixer/main.py", line 130, in <genexpr>
for name, value in defaults.items()
File "/home/cllamach/PythonProjects/mixer/mixer/mix_types.py", line 220, in gen_value
return type_mixer.gen_field(field)
File "/home/cllamach/PythonProjects/mixer/mixer/main.py", line 209, in gen_field
return self.gen_value(field.name, field, unique=unique)
File "/home/cllamach/PythonProjects/mixer/mixer/main.py", line 254, in gen_value
gen = self.get_generator(field, field_name, fake=fake)
File "/home/cllamach/PythonProjects/mixer/mixer/main.py", line 304, in get_generator
field.scheme, field_name, fake, kwargs=field.params)
File "/home/cllamach/PythonProjects/mixer/mixer/backend/sqlalchemy.py", line 178, in make_generator
stype, field_name=field_name, fake=fake, args=args, kwargs=kwargs)
File "/home/cllamach/PythonProjects/mixer/mixer/main.py", line 324, in make_generator
fabric = self.__factory.gen_maker(scheme, field_name, fake)
File "/home/cllamach/PythonProjects/mixer/mixer/factory.py", line 157, in gen_maker
if not func and fcls.__bases__:
AttributeError: Mixer (<class 'tests.test_flask.IpAddressUser'>): 'NoneType' object has no attribute '__bases__'

我把这个错误一直调试到代码中的几个方法,第一个方法get_generator尝试以下操作。。。在

^{pr2}$

奇怪的部分来了。在这个声明里字段.方案具有一个值,特别是sqlalchemy中的Column对象,但当传递到make\u generator方法时,则作为None传递。到目前为止,我还没有看到这两个方法之间的代码片段,也没有用ipdb和其他方法进行过调试。已经尝试用ipdb手动调用该方法,但方案仍然没有通过。在

我知道这可能被认为是一个太特殊的问题,但我想知道是否有人曾经遇到过这种问题,因为这是我第一次。在


Tags: 方法nameinpyfieldhomemainline
2条回答

混合器被未知的柱类型堵塞。它将它在^{}中知道的所有值存储为dict,并调用types.get(column_type),对于无法识别的类型,它当然会返回None。我遇到这种情况是因为我用^{}定义了两个自定义SQLAlchemy类型。在

要解决这个问题,您必须将您的类型monkey补丁到混音器的类型系统中。我是这样做的:

def _setup_mixer_with_custom_types():
    from mixer._faker import faker
    from mixer.backend.sqlalchemy import (
        GenFactory,
        mixer,
    )
    from myproject.customcolumntypes import (
        IntegerTimestamp,
        UTCDateTimeTimestamp,
    )

    def arrow_generator():
        return arrow.get(faker.date_time())

    GenFactory.generators[IntegerTimestamp] = arrow_generator
    GenFactory.generators[UTCDateTimeTimestamp] = arrow_generator

    return mixer

mixer = _setup_mixer_with_custom_types()

请注意,实际上您不必触摸GenFactory.types,因为如果混音器可以直接在GenFactory.generators上找到您的类型,它只是一个中间步骤,Mixer会跳过它。在

在我的例子中,我还必须定义一个自定义生成器(以适应Arrow),但您可能不需要。Mixer使用fake-factory库来生成假数据,您可以通过查看^{}dict来查看它们在使用什么

您必须将列类型放入^{},默认情况下,它只包含一些标准类型。您可以使用子类GenFactory,而不是monkey patching,然后在生成Mixer时指定自己的类。在

在本例中,我们将自定义GenFactory和{}的子类变体:

from mixer.backend.sqlalchemy import Mixer, GenFactory
from customtypes import CustomType    # The column type

def get_mixer():
    class CustomFactory(GenFactory):
        # No need to preserve entries, the parent class attribute is
        # automatically extended through GenFactory's metaclass
        generators = {
            CustomType: lambda: 42    # Or any other function
        }

    return Mixer(factory=CustomFactory)

你可以使用任何你喜欢的函数作为生成器,它只需返回所需的值。有时,直接使用faker中的内容就足够了。在

同样,还可以自定义GenFactory的其他属性,即fakers和{}。在

相关问题 更多 >