Inserción masiva SQLalchemy con relación uno a uno

Tengo el siguiente modelo donde TableA y TableB tienen una relación de 1 a 1:

class TableA(db.Model): id = Column(db.BigInteger, primary_key=True) title = Column(String(1024)) table_b = relationship('TableB', uselist=False, back_populates="table_a") class TableB(db.Model): id = Column(BigInteger, ForeignKey(TableA.id), primary_key=True) a = relationship('TableA', back_populates='table_b') name = Column(String(1024)) 

cuando inserto 1 registro todo va bien:

 rec_a = TableA(title='hello') rec_b = TableB(a=rec_a, name='world') db.session.add(rec_b) db.session.commit() 

pero cuando trato de hacer esto para la mayoría de los registros:

 bulk_ = [] for title, name in zip(titles, names): rec_a = TableA(title=title) bulk_.append(TableB(a=rec_a, name=name)) db.session.bulk_save_objects(bulk_) db.session.commit() 

Me sale la siguiente excepción:

 sqlalchemy.exc.InternalError: (pymysql.err.InternalError) (1364, "Field 'id' doesn't have a default value") 

¿Estoy haciendo algo mal? ¿Configuré mal el modelo? ¿Hay una manera de cometer masivamente este tipo de datos?

El error que ves es lanzado por Mysql. Se queja de que el bash de insertar registros en table_b viola la restricción de clave externa.

Una técnica podría ser escribir todos los títulos en una statement masiva, luego escribir todos los nombres en una segunda statement masiva. Además, nunca he pasado las relaciones con éxito a las operaciones en masa, este método se basa en la inserción de valores simples.

 bulk_titles = [TableA(title=title) for title in titles] session.bulk_save_objects(bulk_titles, return_defauls=True) bulk_names = [TableB(id=title.id, name=name) for title, name in zip(bulk_titles, names)] session.bulk_save_objects(bulk_names) 

return_defaults=True es necesario anteriormente porque necesitamos title.id en la segunda operación masiva. Pero esto reduce en gran medida las ganancias de rendimiento de la operación a granel

Para evitar la degradación del rendimiento debido a return_defauts=True , puede generar las claves primarias de la aplicación, en lugar de la base de datos, por ejemplo, utilizando uuids, o obteniendo el ID máximo en cada tabla y generando un rango desde ese valor inicial.

Otra técnica podría ser escribir su statement de inserción masiva utilizando el núcleo sqlalchemy o texto sin formato.