1

I am developing a python module. My module needs getting data from database various times. I am writing a data-layer class with sole motive of writing all the functions which hits DB at same place and calling these data-layer class methods from different method of my module.

I tried below code:

class datalayer:
   cur = None;     #Cursor which would be used by all methods
   def __init__(self):
     conn=sqlite3.connect(DB_NAME);
     cur=conn.cursor();

   def getEmpData(self,flowId):
     sql= "Select * from emp"
     cur.execute(sql);
     rows = cur.fetchall(); 
     return rows;

   def getManData(self,flowId):
     sql= "Select * from manager"
     cur.execute(sql);
     rows = cur.fetchall(); 
     return rows;

Once this is done I am creating instances of same class in classes where I want to hit DB, like:

class example1:
  def ex1():
    do_something()
    datalayerInstance =  datalayer();
    datalayerInstance.getEmpData();

But even if a do above each time the instance of data-layer class is created a new cursor object would be created. I want to avoid this and create a cursor object just once and use the same through the class. How can this be achieved?

Also, I tried using static method, but that too is not solving my problem.

Please help as I am new to Python.

Mayank Jain
  • 2,504
  • 9
  • 33
  • 52

4 Answers4

2

datalayer.py

datalayerInstance =  datalayer();

def get_datalayerinstance():
    return datalayerInstance

example.py

import datalayer
datalayerInstance = get_datalayerinstance();
laike9m
  • 18,344
  • 20
  • 107
  • 140
2

You want a singleton

Creating a singleton in python

class Singleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class Logger(object):
    __metaclass__ = Singleton

http://python-3-patterns-idioms-test.readthedocs.org/en/latest/Singleton.html

class OnlyOne:
    class __OnlyOne:
        def __init__(self, arg):
            self.val = arg
        def __str__(self):
            return repr(self) + self.val
    instance = None
    def __init__(self, arg):
        if not OnlyOne.instance:
            OnlyOne.instance = OnlyOne.__OnlyOne(arg)
        else:
            OnlyOne.instance.val = arg
    def __getattr__(self, name):
        return getattr(self.instance, name)
Naib
  • 999
  • 7
  • 20
0

What you want is a singleton. To do this you could override __new__ so that everytime you have a new datalayer object created, it uses the same cursor.

class datalayer(object):
    _cur = None;     #Cursor which would be used by all methods

    def __new__(cls, *args, **kwargs):
        if not cls._cur:
            conn=sqlite3.connect(DB_NAME);
            cls._cur = conn.cursor();
        return cls._cur

   def getEmpData(self,flowId):
     sql= "Select * from emp"
     cls._cur.execute(sql);
     rows = cls._cur.fetchall(); 
     return rows;

   def getManData(self,flowId):
     sql= "Select * from manager"
     cls._cur.execute(sql);
     rows = cls._cur.fetchall(); 
     return rows;

It should work although it might not be the prettiest way of doing thigs, there are others much more simple and elegant.
The only advantage is that this would not require you to change all your code.

Answer adapted from this one : https://stackoverflow.com/a/1810367/2549230

Community
  • 1
  • 1
d6bels
  • 1,432
  • 2
  • 18
  • 30
0

You don't seem to be setting the cursor as an attribute on the datalayer class in your initialization method.

class DataLayer(object):
    cur = None

    def __init__(self):
        if DataLayer.cur is None:
            conn = sqlite3.connect(DATABASE)
            DataLayer.cur = conn.cursor()

    def get_employee_data(self, flow_id):
        sql = "Select * from emp"
        self.cur.execute(sql);
        return self.cur.fetchall(); 

I changed some names from your sample to the more accepted standard in python. A thing to note is this sample will not be safe to use in concurrent environments.

Justin Fay
  • 2,576
  • 1
  • 20
  • 27