Bildiğim kadarıyla, ORM'nin toplu girişler yayınlamasını sağlamanın bir yolu yok. Bunun altında yatan nedenin, SQLAlchemy'nin her nesnenin kimliğini (yani, yeni birincil anahtarları) takip etmesi gerektiğine ve toplu girişlerin buna engel olduğuna inanıyorum. Örneğin, foo
tablonuzun bir id
sütun içerdiğini ve bir Foo
sınıfa eşlendiğini varsayarsak :
x = Foo(bar=1)
print x.id
# None
session.add(x)
session.flush()
# BEGIN
# INSERT INTO foo (bar) VALUES(1)
# COMMIT
print x.id
# 1
SQLAlchemy x.id
başka bir sorgu yayınlamadan değerini aldığından , değeri doğrudan INSERT
ifadeden aldığı sonucuna varabiliriz . Oluşturulan nesnelere aynı örnekler üzerinden daha sonra erişmeniz gerekmiyorsa , eklemeniz için ORM katmanını atlayabilirsiniz:
Foo.__table__.insert().execute([{'bar': 1}, {'bar': 2}, {'bar': 3}])
# INSERT INTO foo (bar) VALUES ((1,), (2,), (3,))
SQLAlchemy bu yeni satırları mevcut nesnelerle eşleştiremez, bu nedenle sonraki işlemler için bunları yeniden sorgulamanız gerekir.
Eski veriler söz konusu olduğunda, oturumun veritabanının oturum dışında ne zaman değiştirildiğini bilmek için yerleşik bir yolu olmadığını hatırlamak yararlıdır. Mevcut örnekler üzerinden harici olarak değiştirilmiş verilere erişmek için, örneklerin süresi dolmuş olarak işaretlenmelidir . Bu, varsayılan olarak açık olur session.commit()
, ancak session.expire_all()
veya arayarak manuel olarak da yapılabilir session.expire(instance)
. Bir örnek (SQL ihmal edildi):
x = Foo(bar=1)
session.add(x)
session.commit()
print x.bar
# 1
foo.update().execute(bar=42)
print x.bar
# 1
session.expire(x)
print x.bar
# 42
session.commit()
süresi dolduğundan x
, ilk print ifadesi örtük olarak yeni bir işlemi açar ve x
özniteliklerini yeniden sorgular . İlk print ifadesini yorumlarsanız, ikincisinin şimdi doğru değeri aldığını fark edeceksiniz, çünkü yeni sorgu güncelleme sonrasına kadar yayınlanmayacaktır.
Bu, işlemsel izolasyon açısından mantıklıdır - işlemler arasında yalnızca harici değişiklikleri almalısınız. Bu sizi sorun yaratıyorsa, hemen ulaşmak yerine uygulamanızın işlem sınırlarını netleştirmenizi veya yeniden düşünmenizi öneririm session.expire_all()
.