0

I'm creating a Database class for testing. This is the basic idea; build a database at instantiation, test with it, then delete it when the testing is done. I'd like to use the __del__ function to drop the schema when the object is destroyed.

    def __init__(self):
        dbinfo = dbinfo
        with open('create_test_db_sql', 'r') as sql_file:
            query = sql_file.read()
        connection = self.connect_to_database()
        cur = connection.cursor()
        cur.execute(query)
        connection.commit()

    def connect_to_database(self):
        return psycopg2.connect(dbinfo)

    def __del__(self):
        print("done")
        conn = self.connect_to_database()
        cur = conn.cursor()
        cur.execute("DROP SCHEMA simulator_db_test CASCADE")
        connection.commit()

Whenever I try to run this I get this python error

Exception ignored in: <function TestDatabase.__del__ at 0x0000017AC504E430>
Traceback (most recent call last):
  File "Tests\TestDatabase.py", line 25, in __del__
  File "venv\lib\site-packages\psycopg2\__init__.py", line 121, in connect
  File "venv\lib\site-packages\psycopg2\extensions.py", line 163, in make_dsn
  File "venv\lib\site-packages\psycopg2\extensions.py", line 163, in <listcomp>
  File "venv\lib\site-packages\psycopg2\extensions.py", line 181, in _param_escape
ImportError: sys.meta_path is None, Python is likely shutting down

Not sure what this error means and there don't seem to be any explanations out there except for specific situations.

What does this error mean? It only occurs when I try to connect to the database. I've tried running other code such as print statements and those run as expected in the __del__ method.

LukeDev
  • 509
  • 4
  • 19
  • 1
    So your are trying to override the builtin in `__del__` method and if so why? See this [__del__](https://stackoverflow.com/questions/1481488/what-is-the-del-method-and-how-do-i-call-it) for the gotchas. Why not just make this `def drop_schema()`? – Adrian Klaver Jun 01 '22 at 15:01
  • @AdrianKlaver My end goal is to automate my tests using pytest and GitLab CI/CD. I wanted the Schema to be cleaned up automatically when the test database object is destroyed – LukeDev Jun 01 '22 at 15:58
  • 1
    Did you read the link I sent? My guess is you are being caught by object reference still in flight when you run the `__del__`. If you are dropping/deleting the database the schema is going to dropped as a part of that anyway as a `schema` is a 'child' of a database. Same on the other end the `schema` will be built as part of the database creation. – Adrian Klaver Jun 01 '22 at 17:04
  • You could consider using an [atexit handler](https://docs.python.org/3/library/atexit.html) to execute your teardown code safely. – snakecharmerb Jun 02 '22 at 09:34
  • @AdrianKlaver I understand that, but if the __del__ method never runs, the schema will still exists on the local server. This should also run anywhere a postgre server is available – LukeDev Jun 02 '22 at 15:15
  • What I am saying is there is no reason to run the `__del__`. When you drop the database the schema goes with it. – Adrian Klaver Jun 02 '22 at 15:26
  • @AdrianKlaver I'm not ever dropping the database – LukeDev Jun 02 '22 at 16:43
  • Then you need to rewrite this: "...build a database at instantiation, test with it, then delete it when the testing is done.". When you do provide a detailed explanation of what you are doing and the code you are doing it with. FYI, the simplest thing would be to `DROP DATABASE ...` and then `CREATE DATABASE ...` for new test. – Adrian Klaver Jun 02 '22 at 17:46

0 Answers0