Reputation: 699
I have started writing a simple module for mongodb to use. I am new to python and I have been a problem with the code I wrote:
import pymongo
class mongoDB():
conn = object
def __init__(self):
global conn
self.conn = pymongo.Connection("localhost",27017)
def CreateCollection(self,name =""):
self.dbCollection = conn.name
return self.dbCollection
if __name__ == '__main__':
database = mongoDB
collection = database.CreateCollection("Hello")
Firstly I think there are probably few things wrong with my code if you can spot it and correct me. Also I am keep getting this erro:
collection = database.CreateCollection("Hello")
TypeError: unbound method CreateCollection() must be called with mongoDB
instance as first argument (got str instance instead)
I want to be able to create the connection in the constructor of the class and then have a method for creating a collection and returning it, and also another method to insert delete and update the entities
Upvotes: 3
Views: 13204
Reputation: 4022
So, syntax wise you have a number of problems. It looks like you're mixing a couple of tutorials in different ways. So, firstly I'll explain what is going on with your code and explain why you're seeing what you're seeing:
import pymongo
class mongoDB(): # you don't need ()'s here - only if you are inheriting classes
# you could inherit from object here, which is a good practice
# by doing class mongoDb(object):, otherwise you can just take
# them out
conn = object # here, you're defining a class member - global for all instances
# generally, you don't instantiate an object pointer like this,
# you would set it to None instead. It won't fail doing this,
# but it's not "right"
def __init__(self):
# the __init__ method is the constructor method - this will
# allow you to initialize a particular instance of your class, represented
# by the self argument. This method is called when you call the class, i.e.
# inst = mongoDb()
# in this case, the conn variable is not a global. Globals are defined
# at the root module level - so in this example, only pymongo is a global
# conn is a class member, and would be accessed by doing mongoDB.conn
global conn
# with that being said, you're initializing a local variable here called conn
# that is not being stored anywhere - when this method finishes, this variable
# will be cleaned up from memory, what you are thinking you're doing here
# should be written as mongoDB.conn = pymongo.Connection("localhost", 27017)
conn = pymongo.Connection("localhost",27017)
def CreateCollection(name =""):
# there is one of two things you are trying to do here - 1, access a class
# level member called conn, or 2, access an instance member called conn
# depending on what you are going for, there are a couple of different ways
# to address it.
# all methods for a class, by default, are instance methods - and all of them
# need to take self as the first argument. An instance method of a class
# will always be called with the instance first. Your error is caused because
# you should declare the method as:
# def CreateCollection(self, name = ""):
# The alternative, is to define this method as a static method of the class -
# which does not take an instance but applies to all instances of the class
# to do that, you would add a @staticmethod decorator before the method.
# either way, you're attempting to access the global variable "conn" here,
# which again does not exist
# the second problem with this, is that you are trying to take your variable
# argument (name) and use it as a property. What python is doing here, is
# looking for a member variable called name from the conn object. What you
# are really trying to do is create a collection on the connection with the
# inputed name
# the pymongo class provides access to your collections via this method as a
# convenience around the method, create_collection. In the case where you
# are using a variable to create the collection, you would call this by doing
# conn.create_collection(name)
# but again, that assumes conn is what you think it is, which it isn't
dbCollection = conn.name
return dbCollection
if __name__ == '__main__':
# here you are just creating a pointer to your class, not instantiating it
# you are looking for:
# database = mongoDB()
database = mongoDB
# this is your error, because of the afore mentioned lack of 'self' argument
collection = database.CreateCollection("Hello")
I'd say have a look through the Pep-8 (http://www.python.org/dev/peps/pep-0008/) coding style guides (very helpful) to learn about how to make your code "flow" pythonically.
Having gone through your code to explain what is going on - this is what you are ultimately trying to do:
import pymongo
class MongoDB: # Classes generally are camel-case, starting with uppercase
def __init__(self, dbname):
# the __init__ method is the class constructor, where you define
# instance members. We'll make conn an instance member rather
# than a class level member
self._conn = pymongo.Connection("localhost", 27017)
self._db = self._conn[dbname]
# methods usually start with lowercase, and are either camel case (less desirable
# by Python standards) or underscored (more desirable)
# All instance methods require the 1st argument to be self (pointer to the
# instance being affected)
def createCollection(self, name=""):
return self._db[name]
if __name__ == '__main__':
# you want to initialize the class
database = MongoDB("Hello")
collection = database.createCollection("MyTable")
Given that tho - what is the goal of writing this class wrapper? The same could be written as:
import pymongo
conn = pymongo.Connection('localhost', 27017)
database = conn["Hello"]
collection = database["MyTable"]
If you're trying to create a larger API wrapped around the pymongo database, then I'd recommend looking into some ORM modules that have already been built. There are some out there - not 100% sure which ones are available for MongoDB, but the one I use (I am biased, I wrote it) is called ORB, and can be found at http://docs.projexsoftware.com/api/orb
Upvotes: 19
Reputation: 10695
This is not a specific answer to how to solve your problem, but instead an answer for how to step through what you want to do and work on simpler problems as they arise:
1) Forget about classes at first, and instead
2) Use the Python command line or a Python program like IDLE,
3) To establish your goals by writing calls to open the MongoDB database to accomplish your task or tasks. In other words, write the simplest code to accomplish your goals before worrying about classes.
4) Once you get that done, and feel good to move on, then write a test class using the documentation. My link is one of many you could find.
5) I think part, but not all, of your problem is your class is not set up correctly. My class -- not shown completely -- is as follows:
class GlobalData:
def set_xfer_date(self, value):
self.xfer_date = value
self.date_str = str(value)
self.xfer_date_base = self.date_str[0:10] + " " + "00:00:00"
# Now build tomorrow.
self.xfer_date_tomorrow = datetime.today() + timedelta(1)
self.date_str_tomorrow = str(self.xfer_date_tomorrow)
self.xfer_date_tomorrow = \
self.date_str_tomorrow[0:10] + " " + "00:00:00"
self.section_totals = {}
self.billable_reads = {}
def set_xfer_fnam_out(self, value):
self.xfer_fnam_out = value
def set_xfer_dir_in(self, value):
self.xfer_dir_in = value
.
.
.
def get_billable_reads(self):
return self.billable_reads
One of the problems I see is you are not referring to data using self.
Good luck.
Upvotes: 1