Autant que je sache, il n'y a aucun moyen d'obtenir l'ORM à la question des insertions. Je crois que la raison sous-jacente est que SQLAlchemy besoin de garder une trace de chaque objet de l'identité (par exemple, de nouvelles clés primaires), et des insertions les en empêcher. Par exemple, en supposant que votre foo
tableau contient un id
colonne et correspond à un Foo
classe:
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
Depuis SQLAlchemy ramassé la valeur de x.id
sans émission d'une autre requête, nous pouvons en déduire qu'il a obtenu la valeur directement à partir de l' INSERT
déclaration. Si vous n'avez pas besoin de l'accès ultérieur à la création des objets via le même cas, vous pouvez ignorer la couche ORM pour votre encart:
Foo.__table__.insert().execute([{'bar': 1}, {'bar': 2}, {'bar': 3}])
# INSERT INTO foo (bar) VALUES ((1,), (2,), (3,))
SQLAlchemy ne peut pas correspondre à ces nouvelles lignes avec les objets existants, de sorte que vous aurez à les interroger à nouveau pour toute la suite des opérations.
Autant que des données obsolètes, il est utile de rappeler que la session n'a pas de moyen de savoir si la base de données est modifié en dehors de la session. Afin d'accéder à l'extérieur données modifiées par les instances existantes, le cas, il doit être marqué comme expiré. Ce qui se passe par défaut sur session.commit()
, mais peut être fait manuellement en appelant session.expire_all()
ou session.expire(instance)
. Un exemple SQL (omis):
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()
expire x
, de sorte que la première instruction print implicitement ouvre une nouvelle transaction et re-requêtes x
s'attributs. Si vous commentez la première instruction d'impression, vous remarquerez que le second reprennent la valeur correcte, parce que la nouvelle requête n'est pas émis jusqu'à ce qu'après la mise à jour.
Cela fait sens du point de vue de l'isolation transactionnelle - vous ne devez ramasser externe modifications entre les transactions. Si cela vous cause problème, je te suggère de clarifier ou de re-penser de votre application, les limites de transaction au lieu de rejoindre immédiatement pour session.expire_all()
.