On Fri, May 8, 2015 at 5:50 PM, Carl Meyer <carl@oddbird.net> wrote:
Hi Marc,
You'd need to use a different db connection, since what you're trying to
On 05/08/2015 07:15 AM, Marc Aymerich wrote:
> I'm using atomic requests, but one of my views needs to save a model
> regardless of wheter the current transaction rolls back or not.
>
> I'm confused about how to proceed with the current autocommit behaviour.
> Do I need to use a different db connection? or perhaps there is some way
> of telling django to ignore autocommit for some particular block ?
do violates the very nature of a database transaction. If you were just
trying to run some raw SQL, you could establish the separate connection
yourself manually, but if you're trying to save a Django model, you'll
probably need a second connection defined in your DATABASES setting.
Possible alternatives:
- If you're using a task queuing system (like Celery or rq), queue a
task to perform the save; you can do this without making it conditional
on the transaction committing, as long as your task queue is using a
store other than your primary database (e.g. Redis or RabbitMQ). Usually
when people do this it's unintentional and a bug (they really wanted the
task to execute only if the current transaction committed), but in your
case it could be a feature.
Yep, the thing is that I need to have this instance saved before handling it to a worker process, the worker process uses it and if something goes wrong on the main thread then the worker has an object that does not exists on the database. Now I realize that I can just catch the IntegrityError and re-save the object on the worker thread ;)
obj.pk = None
obj.save()
- Switch from ATOMIC_REQUESTS to explicit use of transaction.atomic() in
your views, so that you can place this "no matter what" save in its own
transaction.
I've been doing something on those lines, but now I have this corner case which I have surouding code that needs to be wrapped up in a transaction :(
For the record, after exploring django.db I realize of 2 more alternative ways of dealing with this situation:
1) because the connection pool is a local thread object, you can just fireup a separate thread, so it will have fresh connections :)
t = threading.Thread(target=backend.create_log, args=args)
t.start()
log = t.join()
2) because a new connection is created for each settings.DATABASES, it is easy to have new connections with a fake database. I've also created a context manager for that
from django import db
from django.conf import settings as djsettings
class fresh_connection(object):
def __init__(self, origin, target):
self.origin = origin
self.target = target
def __enter__(self):
djsettings.DATABASES[self.target] = djsettings.DATABASES[self.origin]
# Because db.connections.datases is a cached property
db.connections = db.utils.ConnectionHandler()
def __exit__(self, type, value, traceback):
db.connections[self.target].close()
djsettings.DATABASES.pop(self.target)
with fresh_connection('default', 'other_default'):
log = backend.create_log(*args, using='other_default')
log._state.db = 'default'
Carl
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/554CDB37.7060503%40oddbird.net.
For more options, visit https://groups.google.com/d/optout.
Marc
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CA%2BDCN_tc946DGihEAu1xqJOgHR8U4td%2Bb-TPS7zu8xAs1jQnnA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
No comments:
Post a Comment