I have a number of factory objects that look like the following:
class OperatorFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta:
model = Operator
sqlalchemy_session = Session()
sqlalchemy_session_persistence = 'commit'
operator = 'equals'
They all share that same Meta
inner class and have distinct models, but they also share those sqlalchemy_session
and sqlalchemy_session_persistence
lines.
My question is, is it possible to write this object in a more DRY (don't repeat yourself) fashion where I don't have to constantly include the lines sqlalchemy_session = Session()
and sqlalchemy_session_persistence = 'commit'
?
So far I have at least a dozen factories and it's getting repetitive.
CodePudding user response:
Instead of having Meta
as an inner-class you can make it a base class and just have factories inherit off it. As you've said they have distinct models you can simply provide a parameter for that to __init__
. Take the following for example:
class Meta:
def __init__(self, Operator):
model = Operator
sqlalchemy_session = Session()
sqlalchemy_session_persistence = 'commit'
class Factory1(Meta, factory.alchemy.SQLAlchemyModelFactory):
def __init__(self):
op = 'equals'
super.__init__(op)
class Factory2(Meta, factory.alchemy.SQLAlchemyModelFactory):
def __init__(self):
op = 'lessthan'
super.__init__(op)
CodePudding user response:
I'm not 100% certain what sessions you want to be shared, the only documentation I could find talks about sharing sessions between all factories but you are generating a separate session for each factory class but not for every instance. (it is a class variable so it is shared between all instances)
Assuming this was an oversight and you actually want a single session for all Meta
fields, you would create a base class for the Meta class:
class BaseMeta:
# now this sessions is shared between ALL factories
sqlalchemy_session = Session()
sqlalchemy_session_persistence = 'commit'
class OperatorFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta(BaseMeta):
model = Operator
operator = 'equals'
alternatively if you want each class to have their own session then you may want a factory function for your meta class of your factory class.
def generate_meta_options(model_):
class Meta:
model = model_
sqlalchemy_session = Session()
sqlalchemy_session_persistence = 'commit'
return Meta
class OperatorFactory(factory.alchemy.SQLAlchemyModelFactory):
Meta = generate_meta_options(Operator)
operator = 'equals'
If the intention is instead to have a separate session for every instance I'm not sure what should be done, I can't figure the relevant documentation on how the factory objects are instantiated.