【问题标题】:Why isn't SQLAlchemy translating this object generated by a FactoryBoy SubFactory into a foreign key?为什么 SQLAlchemy 不将 FactoryBoy SubFactory 生成的这个对象翻译成外键?
【发布时间】:2015-08-07 07:59:00
【问题描述】:

我正在使用 Flask 和 SQLAlchemy(通过 Flask-SQLAlchemy 扩展)以及 Factory_Boy

我的GearItem 模型有一个指向GearCategory 的外键。 Factory_Boy 通过 SubFactory 函数来处理这个问题,该函数创建在原始工厂中用作外键的对象。

这是我的模型定义:

class GearCategory(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Text, unique=True, nullable=False)
    gear_items = db.relationship('GearItem', backref='category',
            lazy='dynamic', order_by='GearItem.name')

class GearItem(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Text, nullable=False, index=True)
    category_id = db.Column(db.Integer, db.ForeignKey('gear_category.id'), index=True)

这是我的 factory_boy Factory 定义:

class GearCategoryFactory(BaseFactory): # Based on factory.alchemy.SQLAlchemyModelFactory
    class Meta:
        model = gear_models.GearCategory
    name = factory.LazyAttribute(lambda n: faker.word())

class GearItemFactory(BaseFactory):
    class Meta:
        model = gear_models.GearItem
    name = factory.LazyAttribute(lambda n: faker.word())
    category_id = factory.SubFactory(GearCategoryFactory)

我可以毫无问题地调用GearItemFactory(),它显然会生成一个GearItem 和一个打算用作外键的父级GearCategory

但是,当我调用db.session.flush() 时,SQLAlchemy 不会将SubFactory 创建的对象转换为可用作外键的整数。相反,它尝试将对象本身传递给底层数据库驱动程序,然后它抱怨不知道如何处理GearCategory 类型的对象。

我得到的错误是sqlalchemy.exc.ProgrammingError: (db_driver) can't adapt type 'GearCategory' [SQL: 'INSERT INTO gear_item (...

我做错了什么?

【问题讨论】:

  • 您需要在此处展示您实际创建对象的方式。但我也不知道工厂男孩是什么,它似乎是这里的一些主要元素,所以也许给他们发电子邮件寻求支持。

标签: python sqlalchemy flask-sqlalchemy factory-boy


【解决方案1】:

问题在于GearItemFactory 定义为外键数据库ID 指定了一个Python 对象引用。 sqlalchemy 将 Python 对象转换为数据库外键 ID 没有问题。但是在我的工厂中,我指定了对象到数据库的列映射而不是对象到对象的映射,因此 SQLAlchemy(正确地)认为我想将 Python 对象直接传递给数据库。只需将工厂外键更改为对象到对象的映射,sqlalchemy 将在后台处理实际的数据库 FK 列。

这是虚线:

category_id = factory.SubFactory(GearCategoryFactory)

看看GearCategory 上的backref 是如何命名为category 而不是category_id? 更新该行以使用 category 可以解决问题:

category = factory.SubFactory(GearCategoryFactory)

【讨论】:

    猜你喜欢
    • 2013-06-16
    • 1970-01-01
    • 2020-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    • 2013-05-16
    相关资源
    最近更新 更多