How to pass a class_name into a function to use in Sqlalchemy Query











up vote
1
down vote

favorite












I am trying to a build a User-class function with an SQLAlchemy query inside that allows me to count the User-records on different tables (based on his id). To avoid multiple function codings, I tried to define a generic function where I receive the db.modell class as a parameter from a Jinja2 call like:



{{ current_user.count('Customer') }}


or



{{ current_user.count('Player') }}


But I end up in errors that Python does not interpret the given class_name parameter as a real Class. He complains that class_name doesn't have a function id.
Of course I could specify specific User Functions with a specific query for each class but I tried to avoid those duplicate codings.



Any ideas on how to deal with this?



class User(db.Model): 
__tablename__='user'
id = Column(Integer, primary_key=True)


def count(self, class_name):
s = db.session()
count = s.query(class_name).filter(class_name.id == self.id).count()
return count

class Player(db.Model):
__tablename__='player'
id = Column(Integer, primary_key=True)

class Customer(db.Model):
__tablename__='Customer'
id = Column(Integer, primary_key=True)


Thanks in advance



Michael










share|improve this question




















  • 1




    Why not just pass the class itself? Naturally class_name does not have an attribute named id, because you have passed string values
    – Ilja Everilä
    18 hours ago

















up vote
1
down vote

favorite












I am trying to a build a User-class function with an SQLAlchemy query inside that allows me to count the User-records on different tables (based on his id). To avoid multiple function codings, I tried to define a generic function where I receive the db.modell class as a parameter from a Jinja2 call like:



{{ current_user.count('Customer') }}


or



{{ current_user.count('Player') }}


But I end up in errors that Python does not interpret the given class_name parameter as a real Class. He complains that class_name doesn't have a function id.
Of course I could specify specific User Functions with a specific query for each class but I tried to avoid those duplicate codings.



Any ideas on how to deal with this?



class User(db.Model): 
__tablename__='user'
id = Column(Integer, primary_key=True)


def count(self, class_name):
s = db.session()
count = s.query(class_name).filter(class_name.id == self.id).count()
return count

class Player(db.Model):
__tablename__='player'
id = Column(Integer, primary_key=True)

class Customer(db.Model):
__tablename__='Customer'
id = Column(Integer, primary_key=True)


Thanks in advance



Michael










share|improve this question




















  • 1




    Why not just pass the class itself? Naturally class_name does not have an attribute named id, because you have passed string values
    – Ilja Everilä
    18 hours ago















up vote
1
down vote

favorite









up vote
1
down vote

favorite











I am trying to a build a User-class function with an SQLAlchemy query inside that allows me to count the User-records on different tables (based on his id). To avoid multiple function codings, I tried to define a generic function where I receive the db.modell class as a parameter from a Jinja2 call like:



{{ current_user.count('Customer') }}


or



{{ current_user.count('Player') }}


But I end up in errors that Python does not interpret the given class_name parameter as a real Class. He complains that class_name doesn't have a function id.
Of course I could specify specific User Functions with a specific query for each class but I tried to avoid those duplicate codings.



Any ideas on how to deal with this?



class User(db.Model): 
__tablename__='user'
id = Column(Integer, primary_key=True)


def count(self, class_name):
s = db.session()
count = s.query(class_name).filter(class_name.id == self.id).count()
return count

class Player(db.Model):
__tablename__='player'
id = Column(Integer, primary_key=True)

class Customer(db.Model):
__tablename__='Customer'
id = Column(Integer, primary_key=True)


Thanks in advance



Michael










share|improve this question















I am trying to a build a User-class function with an SQLAlchemy query inside that allows me to count the User-records on different tables (based on his id). To avoid multiple function codings, I tried to define a generic function where I receive the db.modell class as a parameter from a Jinja2 call like:



{{ current_user.count('Customer') }}


or



{{ current_user.count('Player') }}


But I end up in errors that Python does not interpret the given class_name parameter as a real Class. He complains that class_name doesn't have a function id.
Of course I could specify specific User Functions with a specific query for each class but I tried to avoid those duplicate codings.



Any ideas on how to deal with this?



class User(db.Model): 
__tablename__='user'
id = Column(Integer, primary_key=True)


def count(self, class_name):
s = db.session()
count = s.query(class_name).filter(class_name.id == self.id).count()
return count

class Player(db.Model):
__tablename__='player'
id = Column(Integer, primary_key=True)

class Customer(db.Model):
__tablename__='Customer'
id = Column(Integer, primary_key=True)


Thanks in advance



Michael







python sqlalchemy






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 16 hours ago









lgwilliams

129211




129211










asked 19 hours ago









Michael Huhn

84




84








  • 1




    Why not just pass the class itself? Naturally class_name does not have an attribute named id, because you have passed string values
    – Ilja Everilä
    18 hours ago
















  • 1




    Why not just pass the class itself? Naturally class_name does not have an attribute named id, because you have passed string values
    – Ilja Everilä
    18 hours ago










1




1




Why not just pass the class itself? Naturally class_name does not have an attribute named id, because you have passed string values
– Ilja Everilä
18 hours ago






Why not just pass the class itself? Naturally class_name does not have an attribute named id, because you have passed string values
– Ilja Everilä
18 hours ago














1 Answer
1






active

oldest

votes

















up vote
1
down vote



accepted










It is better to pass the class itself to the function like this:



 def count(self, class_): 
s = db.session()
count = s.query(class_).filter(class_.id == self.id).count()
return count


But if you have to pass a class name for some reason, you can do something like this:



 def count(self, class_name):
class_ = {
'player':Player,
'customer':Customer,
}[class_name.lower()]

s = db.session()
count = s.query(class_).filter(class_.id == self.id).count()
return count


it is not very different but you can do this.



There is also another way, but I don't recommend this:



 def count(self, class_name):
class_ = globals()[class_name]

s = db.session()
count = s.query(class_).filter(class_.id == self.id).count()
return count


this way will just work if everything exists in global scope.
read about globals Here



note that:





  1. Careful to not use class as a name of a variable, class is predefined. use something else like class_


  2. It will raise key errorif you pass a wrong class name in second way. you can handle it with try and except.








share|improve this answer



















  • 1




    your second proposal works really nice.
    – Michael Huhn
    17 hours ago










  • I didnt get the first proposal up and running to pass the class itself. I tried: {{ current_user.count(class ='Player') }} but it didnt work. I believe it because in my template, the class is not known at all ?!
    – Michael Huhn
    17 hours ago








  • 1




    @MichaelHuhn you should remove 's. like this {{ current_user.count(Player) }}
    – mehrdad-pedramfar
    17 hours ago











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237520%2fhow-to-pass-a-class-name-into-a-function-to-use-in-sqlalchemy-query%23new-answer', 'question_page');
}
);

Post as a guest
































1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
1
down vote



accepted










It is better to pass the class itself to the function like this:



 def count(self, class_): 
s = db.session()
count = s.query(class_).filter(class_.id == self.id).count()
return count


But if you have to pass a class name for some reason, you can do something like this:



 def count(self, class_name):
class_ = {
'player':Player,
'customer':Customer,
}[class_name.lower()]

s = db.session()
count = s.query(class_).filter(class_.id == self.id).count()
return count


it is not very different but you can do this.



There is also another way, but I don't recommend this:



 def count(self, class_name):
class_ = globals()[class_name]

s = db.session()
count = s.query(class_).filter(class_.id == self.id).count()
return count


this way will just work if everything exists in global scope.
read about globals Here



note that:





  1. Careful to not use class as a name of a variable, class is predefined. use something else like class_


  2. It will raise key errorif you pass a wrong class name in second way. you can handle it with try and except.








share|improve this answer



















  • 1




    your second proposal works really nice.
    – Michael Huhn
    17 hours ago










  • I didnt get the first proposal up and running to pass the class itself. I tried: {{ current_user.count(class ='Player') }} but it didnt work. I believe it because in my template, the class is not known at all ?!
    – Michael Huhn
    17 hours ago








  • 1




    @MichaelHuhn you should remove 's. like this {{ current_user.count(Player) }}
    – mehrdad-pedramfar
    17 hours ago















up vote
1
down vote



accepted










It is better to pass the class itself to the function like this:



 def count(self, class_): 
s = db.session()
count = s.query(class_).filter(class_.id == self.id).count()
return count


But if you have to pass a class name for some reason, you can do something like this:



 def count(self, class_name):
class_ = {
'player':Player,
'customer':Customer,
}[class_name.lower()]

s = db.session()
count = s.query(class_).filter(class_.id == self.id).count()
return count


it is not very different but you can do this.



There is also another way, but I don't recommend this:



 def count(self, class_name):
class_ = globals()[class_name]

s = db.session()
count = s.query(class_).filter(class_.id == self.id).count()
return count


this way will just work if everything exists in global scope.
read about globals Here



note that:





  1. Careful to not use class as a name of a variable, class is predefined. use something else like class_


  2. It will raise key errorif you pass a wrong class name in second way. you can handle it with try and except.








share|improve this answer



















  • 1




    your second proposal works really nice.
    – Michael Huhn
    17 hours ago










  • I didnt get the first proposal up and running to pass the class itself. I tried: {{ current_user.count(class ='Player') }} but it didnt work. I believe it because in my template, the class is not known at all ?!
    – Michael Huhn
    17 hours ago








  • 1




    @MichaelHuhn you should remove 's. like this {{ current_user.count(Player) }}
    – mehrdad-pedramfar
    17 hours ago













up vote
1
down vote



accepted







up vote
1
down vote



accepted






It is better to pass the class itself to the function like this:



 def count(self, class_): 
s = db.session()
count = s.query(class_).filter(class_.id == self.id).count()
return count


But if you have to pass a class name for some reason, you can do something like this:



 def count(self, class_name):
class_ = {
'player':Player,
'customer':Customer,
}[class_name.lower()]

s = db.session()
count = s.query(class_).filter(class_.id == self.id).count()
return count


it is not very different but you can do this.



There is also another way, but I don't recommend this:



 def count(self, class_name):
class_ = globals()[class_name]

s = db.session()
count = s.query(class_).filter(class_.id == self.id).count()
return count


this way will just work if everything exists in global scope.
read about globals Here



note that:





  1. Careful to not use class as a name of a variable, class is predefined. use something else like class_


  2. It will raise key errorif you pass a wrong class name in second way. you can handle it with try and except.








share|improve this answer














It is better to pass the class itself to the function like this:



 def count(self, class_): 
s = db.session()
count = s.query(class_).filter(class_.id == self.id).count()
return count


But if you have to pass a class name for some reason, you can do something like this:



 def count(self, class_name):
class_ = {
'player':Player,
'customer':Customer,
}[class_name.lower()]

s = db.session()
count = s.query(class_).filter(class_.id == self.id).count()
return count


it is not very different but you can do this.



There is also another way, but I don't recommend this:



 def count(self, class_name):
class_ = globals()[class_name]

s = db.session()
count = s.query(class_).filter(class_.id == self.id).count()
return count


this way will just work if everything exists in global scope.
read about globals Here



note that:





  1. Careful to not use class as a name of a variable, class is predefined. use something else like class_


  2. It will raise key errorif you pass a wrong class name in second way. you can handle it with try and except.









share|improve this answer














share|improve this answer



share|improve this answer








edited 17 hours ago

























answered 18 hours ago









mehrdad-pedramfar

3,30011232




3,30011232








  • 1




    your second proposal works really nice.
    – Michael Huhn
    17 hours ago










  • I didnt get the first proposal up and running to pass the class itself. I tried: {{ current_user.count(class ='Player') }} but it didnt work. I believe it because in my template, the class is not known at all ?!
    – Michael Huhn
    17 hours ago








  • 1




    @MichaelHuhn you should remove 's. like this {{ current_user.count(Player) }}
    – mehrdad-pedramfar
    17 hours ago














  • 1




    your second proposal works really nice.
    – Michael Huhn
    17 hours ago










  • I didnt get the first proposal up and running to pass the class itself. I tried: {{ current_user.count(class ='Player') }} but it didnt work. I believe it because in my template, the class is not known at all ?!
    – Michael Huhn
    17 hours ago








  • 1




    @MichaelHuhn you should remove 's. like this {{ current_user.count(Player) }}
    – mehrdad-pedramfar
    17 hours ago








1




1




your second proposal works really nice.
– Michael Huhn
17 hours ago




your second proposal works really nice.
– Michael Huhn
17 hours ago












I didnt get the first proposal up and running to pass the class itself. I tried: {{ current_user.count(class ='Player') }} but it didnt work. I believe it because in my template, the class is not known at all ?!
– Michael Huhn
17 hours ago






I didnt get the first proposal up and running to pass the class itself. I tried: {{ current_user.count(class ='Player') }} but it didnt work. I believe it because in my template, the class is not known at all ?!
– Michael Huhn
17 hours ago






1




1




@MichaelHuhn you should remove 's. like this {{ current_user.count(Player) }}
– mehrdad-pedramfar
17 hours ago




@MichaelHuhn you should remove 's. like this {{ current_user.count(Player) }}
– mehrdad-pedramfar
17 hours ago


















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237520%2fhow-to-pass-a-class-name-into-a-function-to-use-in-sqlalchemy-query%23new-answer', 'question_page');
}
);

Post as a guest




















































































Popular posts from this blog

Florida Star v. B. J. F.

Error while running script in elastic search , gateway timeout

Adding quotations to stringified JSON object values