0

I'm trying to write a sub class from this class:

class InsertCreateAlter(object):

def __init__(self, url=None, engine=None, connection=None, session=None,
             **kwargs):
    if connection is not None:
        self.engine = connection
    elif engine is not None:
        self.engine = engine
    elif session is not None:
        self.engine = session
    else:
        self.engine = sqlalchemy.create_engine(url, **kwargs)

This was my attempt so far:

class InsertCreateAlterEAV(InsertCreateAlter):


def __init__(self, url=None, engine=None, connection=None, session=None,
             **kwargs):
    InsertCreateAlter.__init__(self, url=None, engine=None, connection=None, session=None,
             **kwargs)
    if connection is not None:
        self.engine = connection
    elif engine is not None:
        self.engine = engine
    elif session is not None:
        self.engine = session
    else:
        self.engine = sqlalchemy.create_engine(url, **kwargs)

When I call the function as:

InsertCreateAlterEAV(session=session)

I got the error:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/IPython/core/interactiveshell.py", line 3267, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-4-ee54fec26f76>", line 2, in <module>
    InsertCreateAlterEAV(session=session)
  File "/Users/asportelli/Documents/gitRepos/etl/etl/eav/InsertCreateAlterEAV.py", line 18, in __init__
    **kwargs)
  File "/Users/asportelli/Documents/gitRepos/etl/etl/insert/InsertCreateAlter.py", line 27, in __init__
    self.engine = sqlalchemy.create_engine(url, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/sqlalchemy/engine/__init__.py", line 425, in create_engine
    return strategy.create(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/sqlalchemy/engine/strategies.py", line 52, in create
    plugins = u._instantiate_plugins(kwargs)
AttributeError: 'NoneType' object has no attribute '_instantiate_plugins'
Blue Moon
  • 4,421
  • 20
  • 52
  • 91
  • Did you tried with `super()`? – shaik moeed May 28 '19 at 10:13
  • How are you calling this? – doctorlove May 28 '19 at 10:14
  • @shaikmoeed yes, no joy as well – Blue Moon May 28 '19 at 10:14
  • @doctorlove I edit it the question – Blue Moon May 28 '19 at 10:16
  • 3
    why is `engine` defaulting to `None` ? Also why are you calling the `__init__()` from parent class instead of constructing it normally ? Even if you feed someting else as `engine` to your child class, your `__init__()` call to parent class feeds it `None`. You also don't assign the result of this `__init__()` call to anything so it's lost immediately. –  May 28 '19 at 10:18
  • Thanks @reportgunner, could you put that in answer with a code example please? – Blue Moon May 28 '19 at 10:20
  • I have absolutely no idea what your classes are supposed to do and I asked questions, therefore I can't, I'm sorry. –  May 28 '19 at 10:22
  • @BlueMoon is your sqlalchemy connection working fine? – xxbinxx May 28 '19 at 10:23
  • Possible duplicate of [Python: How do I make a subclass from a superclass?](https://stackoverflow.com/questions/1607612/python-how-do-i-make-a-subclass-from-a-superclass) –  May 28 '19 at 10:23
  • this is already answered [here](https://stackoverflow.com/a/1608905/10417531) –  May 28 '19 at 10:24
  • @BlueMoon can you post your `create_engine` config – xxbinxx May 28 '19 at 10:25

1 Answers1

3

You should not duplicate the code of the parent class. Do it like this:

class InsertCreateAlterEAV(InsertCreateAlter):
    def __init__(self, url=None, engine=None, connection=None, session=None,
                 **kwargs):
        # Do you have code you want to run before running the parent's __init__?
        # Maybe adding default arguments or changing one of them?
        # Then add that code here.

        # init the parent
        super().__init__(url=url,
                         engine=engine,
                         connection=connection,
                         session=session,
                         **kwargs)

        # Here you can add code after the parent's init code. Maybe for
        # initializing subclass-specific attributes.

In case you are still using Python 2, use InsertCreateAlter.__init__(self, ...


Now let's see what the problem was. You call your subclass as follows:

InsertCreateAlterEAV(session=session)

then your subclass calls the parent class' __init__ method, but with session=None. Therefore, the parent class takes this branch:

else:
        self.engine = sqlalchemy.create_engine(url, **kwargs)

and because kwargs is empty, only url (which is None) is passed to create_engine(). This method does not know how to deal with url==None.

Thus, you get an exception.

Georg Schölly
  • 124,188
  • 49
  • 220
  • 267