问题描述
我正在使用Flask和SQLAlchemy(通过Flask-SQLAlchemy扩展名)以及 Factory_Boy .
I'm using Flask and SQLAlchemy (via the Flask-SQLAlchemy extension) together with Factory_Boy.
我的GearItem
模型具有GearCategory
的外键. Factory_Boy 通过SubFactory
函数处理此问题,该函数在原始对象中创建用作外键的对象工厂.
My GearItem
model has a foreign key to GearCategory
. Factory_Boy handles this through the SubFactory
function that creates the object to be used as the foreign key in the original factory.
这是我的模型定义:
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
定义:
And here are my factory_boy Factory
definitions:
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
.
I can call GearItemFactory()
with no problems and it's clearly generating both a GearItem
and a parent GearCategory
that's intended to be used as the foreign key.
但是,当我调用db.session.flush()
时,SQLAlchemy不会将SubFactory
创建的对象转换为可用作外键的整数.相反,它尝试将对象本身传递给基础数据库驱动程序,该驱动程序随后抱怨说不知道如何处理类型为GearCategory
的对象.
However, when I call db.session.flush()
, SQLAlchemy doesn't translate the object created by the SubFactory
into an integer that can be used as the foreign key. Instead, it tries to pass the object itself to the underlying database driver, which then complains that has no idea how to handle an object of type GearCategory
.
我遇到的错误是sqlalchemy.exc.ProgrammingError: (db_driver) can't adapt type 'GearCategory' [SQL: 'INSERT INTO gear_item (...
我在做什么错了?
推荐答案
问题是GearItemFactory
定义为外键数据库ID指定了Python对象引用. sqlalchemy
将Python对象转换为数据库外键ID没问题.但是,在我的工厂中,我指定了对象到数据库的列映射,而不是对象到对象的映射,因此SQLAlchemy(正确地)认为我想将Python对象直接传递给数据库.只需将工厂外键更改为对象到对象的映射,然后sqlalchemy
将在后台处理实际的数据库FK列.
The problem is that the GearItemFactory
definition specifies a Python object reference for the foreign key database ID. sqlalchemy
has no problem translating Python objects into database Foreign Key ID. However in my factory I specified an object-to-database column mapping rather than an object-to-object mapping, so SQLAlchemy (rightfully) thinks I want to pass the Python object straight to the database. Just need to change the factory foreign key to an object-to-object mapping and sqlalchemy
will handle the actual database FK column behind the scenes.
这是虚线:
category_id = factory.SubFactory(GearCategoryFactory)
看看GearCategory
上的backref
如何命名为category
而不是category_id
?更新该行以使用category
可以解决此问题:
See how the backref
on GearCategory
is named category
not category_id
?Updating that line to use category
fixes the problem:
category = factory.SubFactory(GearCategoryFactory)
这篇关于SQLAlchemy为什么不将FactoryBoy子工厂生成的此对象转换为外键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!