The default connection (i.e. django.db.connection) is different for each thread (#17258).
(self)
| 784 | available_apps = ["backends"] |
| 785 | |
| 786 | def test_default_connection_thread_local(self): |
| 787 | """ |
| 788 | The default connection (i.e. django.db.connection) is different for |
| 789 | each thread (#17258). |
| 790 | """ |
| 791 | # Map connections by id because connections with identical aliases |
| 792 | # have the same hash. |
| 793 | connections_dict = {} |
| 794 | with connection.cursor(): |
| 795 | pass |
| 796 | connections_dict[id(connection)] = connection |
| 797 | |
| 798 | def runner(): |
| 799 | # Passing django.db.connection between threads doesn't work while |
| 800 | # connections[DEFAULT_DB_ALIAS] does. |
| 801 | from django.db import connections |
| 802 | |
| 803 | connection = connections[DEFAULT_DB_ALIAS] |
| 804 | # Allow thread sharing so the connection can be closed by the |
| 805 | # main thread. |
| 806 | connection.inc_thread_sharing() |
| 807 | with connection.cursor(): |
| 808 | pass |
| 809 | connections_dict[id(connection)] = connection |
| 810 | |
| 811 | try: |
| 812 | for x in range(2): |
| 813 | t = threading.Thread(target=runner) |
| 814 | t.start() |
| 815 | t.join() |
| 816 | # Each created connection got different inner connection. |
| 817 | self.assertEqual( |
| 818 | len({conn.connection for conn in connections_dict.values()}), 3 |
| 819 | ) |
| 820 | finally: |
| 821 | # Finish by closing the connections opened by the other threads |
| 822 | # (the connection opened in the main thread will automatically be |
| 823 | # closed on teardown). |
| 824 | for conn in connections_dict.values(): |
| 825 | if conn is not connection and conn.allow_thread_sharing: |
| 826 | conn.validate_thread_sharing() |
| 827 | conn._close() |
| 828 | conn.dec_thread_sharing() |
| 829 | |
| 830 | def test_connections_thread_local(self): |
| 831 | """ |
nothing calls this directly
no test coverage detected