How to clone a sqlalchemy db object with new primary key

匆匆过客 提交于 2020-03-17 09:53:31

问题


I want to clone a sqlalchemy object:

I tried it by

product_obj = products.all()[0] #here products is service name

product_obj.product_uid = 'soemthing' #here product_uid is the pk of product model

products.save(product_obj)

it is just updating the old_object only

here is the code of products.save function

class Service(object):

        __model__ = None

       def save(self, model):
            self._isinstance(model)
            db.session.add(model)
            db.session.commit()
            return model

回答1:


This should work:

product_obj = products.all()[0]

db.session.expunge(product_obj)  # expunge the object from session
make_transient(product_obj)  # http://docs.sqlalchemy.org/en/rel_1_1/orm/session_api.html#sqlalchemy.orm.session.make_transient

product_obj.product_uid = 'something'
db.session.add(product_obj)



回答2:


For sqlalchemy 1.3 I ended up using a helper function.

  1. It copies all the non-primary-key columns from the input model to a new model instance.
  2. It allows you to pass data directly as keyword arguments.
  3. It leaves the original model object unmodified.
def clone_model(model, **kwargs):
    """Clone an arbitrary sqlalchemy model object without its primary key values."""
    # Ensure the model’s data is loaded before copying.
    model.id

    table = model.__table__
    non_pk_columns = [k for k in table.columns.keys() if k not in table.primary_key]
    data = {c: getattr(model, c) for c in non_pk_columns}
    data.update(kwargs)

    clone = model.__class__(**data)
    db.session.add(clone)
    db.session.commit()
    return clone

With this function you can solve the above problem using:

product_obj = products.all()[0]  # Get the product from somewhere.
cloned_product_obj = clone_model(product_obj, product_uid='something')

Depending on your use-case you might want to remove the call to db.session.commit() from this function.


This answer is based on https://stackoverflow.com/a/13752442/769486 (How to get a model’s columns?) and How do I get the name of an SQLAlchemy object's primary key? (How do I get a model’s primary keys?).




回答3:


One possible approach is to use dictalchemy:

new_instance = InstanceModel(**old_instance.asdict())


来源:https://stackoverflow.com/questions/28871406/how-to-clone-a-sqlalchemy-db-object-with-new-primary-key

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