Может session.merge SQLALCHEMY () обновляют его результат с более новыми данными из базы данных?

Мы покрыли это по этому вопросу: , Какова Ваша любимая Visual Studio add-in/setting?

15
задан mvexel 22 July 2014 в 20:42
поделиться

1 ответ

SQLAlchemy спроектирован так, чтобы иметь один объект с каждым идентификатором в сеансе. Но иногда вам нужно воссоздать объект с известной идентичностью, например, когда вы получаете его из сети или когда вы реализуете автономную блокировку, чтобы избежать длинных транзакций. И когда вы создаете объект с известным идентификатором, который может существовать в базе данных, есть вероятность, что сеанс уже отслеживает объект с этим идентификатором. Для этого предназначен метод merge () : он возвращает объект, прикрепленный к сеансу, таким образом избегая дублирования объектов с тем же идентификатором в сеансе. Ниже приведен пример, иллюстрирующий происходящее:

from sqlalchemy import *
from sqlalchemy.orm import *

metadata = MetaData()

t = Table(
    't', metadata,
    Column('id', Integer, primary_key=True),
    Column('state', String(10)),
)

class Model(object): pass

mapper(Model, t)

engine = create_engine('sqlite://')
metadata.create_all(engine)

session = sessionmaker(bind=engine)()

obj1 = Model()
obj1.state = 'value1'
session.add(obj1)
session.commit()
obj_id = obj1.id

obj2 = Model()
obj2.id = obj_id
obj2.state = 'value2'
obj3 = session.merge(obj2)
session.commit()
print obj3 is obj1, obj3 is obj2
print obj3.state

Результат:

True False
value2

Таким образом, session.merge (obj2) обнаруживает, что существует объект с таким же идентификатором ( obj1 ] создан выше), поэтому он объединяет состояние obj2 в существующий объект и возвращает его.

Ниже приведен другой пример, который иллюстрирует состояние загрузки из базы данных:

# ...skipped...

t = Table(
    't', metadata,
    Column('id', Integer, primary_key=True),
    Column('state1', String(10)),
    Column('state2', String(10)),
)

# ...skipped...

obj1 = Model()
obj1.state1 = 'value1-1'
obj1.state2 = 'value2-1'
session.add(obj1)
session.commit()
obj_id = obj1.id
session.expunge_all()

obj2 = Model()
obj2.id = obj_id
obj2.state1 = 'value1-2'
obj3 = session.merge(obj2)
session.commit()
print obj3 is obj1, obj3 is obj2
print obj3.state1, obj3.state2

Результат:

False False
value1-2 value2-1

Теперь объединить () не удалось найти объект с таким же идентификатором в сеансе, поскольку мы удалили его. Также я создал новый объект с частично назначенным состоянием, но остальное загружено из базы данных.

50
ответ дан 1 December 2019 в 00:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: