2

Below is just example code that provides the error I am hoping to get help on fixing, or getting an understanding of a better way to write this. I have a mysql "super" class called mysql_connection. In this class, the connection to the database is made. I also have a few methods within it. One that simply runs "select version()" to show that the connection/query works. I then have a "chktable" method which in this example instantiates a new subclass called "table" which inherits the super class. After instantiating the class, I then call a method within the subclass which attempts to use the the query method in the superclass to run "show tables like 'tbl name'". This is where I get an error.

import mysql.connector
from mysql.connector import errorcode
from mysql.connector.cursor import MySQLCursor

class mysql_connection(object):
    def __init__(self, **kwargs):
        self.connection_options = {}
        self.connection_options['user'] = 'root'
        self.connection_options['password'] = ''
        self.connection_options['host'] = '192.168.33.10'
        self.connection_options['port'] = '3306'
        self.connection_options['database'] = "test"
        self.connection_options['raise_on_warnings'] = True
        self.connect()

    def connect(self):
        try:
            self.cnx = mysql.connector.connect(**self.connection_options)
        except mysql.connector.Error as err:
            if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
                print "Something is wrong with your user name or password"
            elif err.errno == errorcode.ER_BAD_DB_ERROR:
                print "Database does not exists" 
            else:
                print err

    def query(self, statement, data=''):
        cursor = MySQLCursor(self.cnx)
        cursor.execute(statement)
        result = cursor.fetchall()
        cursor.close
        return result

    def get_version(self):
        print self.query("select version()")

    def chktable(self, tb_name):
        tab = table(name=tb_name)
        tab.check_table()

class table(mysql_connection):
    def __init__(self, **kwargs):
        self.name = kwargs['name']

    def check_table(self):
        return super(table, self).query("show tables like '{}".format(self.name))

conn = mysql_connection()
conn.get_version()
conn.chktable("test")

The error that I get is:

$ python example.py
[(u'5.1.73',)]
Traceback (most recent call last):
  File "example.py", line 50, in <module>
    conn.chktable("test")
  File "example.py", line 39, in chktable
    tab.check_table()
  File "example.py", line 46, in check_table
    return super(table, self).query("show tables like '{}".format(self.name))
  File "example.py", line 28, in query
    cursor = MySQLCursor(self.cnx)
    AttributeError: 'table' object has no attribute 'cnx'

I don't fully understand calling back to the super class and how it works with subclasses, so that is likely my issue. I'd also like to know if there is maybe a better way to accomplish this. I was thinking I could get rid of the subclass altogether, but I like the subclass I made so I feel there should be a way around it. A secondary thing I could try would be to put the subclass inside the master class, but I don't think that is correct.

1
  • 1
    Why does your table inherit from the connection?! Commented Dec 6, 2014 at 9:04

1 Answer 1

2

As Jon points out, this is not an appropriate use of inheritance. That is for "is-a" relationships: ie Dog inherits from Animal, because a dog is an animal. But a table is not a connection: a table might use a connection, but that simply means you should assign an instance of the connection to an instance variable in table.

Also, in an inheritance relationship there is usually no good reason for a superclass to know about its subclasses, as you have in the chktable method.

(The actual bug you're seeing is because you haven't called the superclass method in table's __init__, but it's better to fix your structure.)

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. You are correct that it was not an appropriate use of inheritance. Though this was only an example, and the mysql_connnection class is named differently in the real code, my class is a "has a" composition instead of a "is a." With further thought on my code, I have realized that I will not be using the "has a" class anywhere else, so I will be just adding it to the main class. I may go about making an actual mysql connection composition class to decouple it from my main mysql class I am working on.
Great explanation of when to use inheritance and how to handle this situation without it using and instance variable

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.