Why isn't SQLAlchemy translating this object generated by a FactoryBoy SubFactory into a foreign key?

╄→гoц情女王★ 提交于 2019-12-07 08:41:09

问题


I'm using Flask and SQLAlchemy (via the Flask-SQLAlchemy extension) together with Factory_Boy.

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.

Here are my model definitions:

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)

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)

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.

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.

The error that I'm getting is sqlalchemy.exc.ProgrammingError: (db_driver) can't adapt type 'GearCategory' [SQL: 'INSERT INTO gear_item (...

What am I doing wrong?


回答1:


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.

This is the broken line:

category_id = factory.SubFactory(GearCategoryFactory)

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)


来源:https://stackoverflow.com/questions/31872497/why-isnt-sqlalchemy-translating-this-object-generated-by-a-factoryboy-subfactor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!