开发者

SQLAlchemy: Dynamically loading tables from a list

开发者 https://www.devze.com 2023-04-09 13:02 出处:网络
I am trying to create a program that loads in over 100 tables from a database so that I can change all appearances of a user\'s user id.

I am trying to create a program that loads in over 100 tables from a database so that I can change all appearances of a user's user id.

Rather than map all of the tables individually, I decided to use a loop to map each of the tables using an array of objects. This way, the table definitions can be stored in a config file and later updated.

Here is my code so far:

def init_model(engine):
    """Call me before using any of the tables or classes in the model"""
    meta.Session.configure(bind=engine)
    meta.engine = engine

class Table:
    tableID = ''
    primaryKey = ''
    pkType = sa.types.String()
    class mappedClass(object):
        pass


WIW_TBL = Table()
LOCATIONS_TBL = Table()

WIW_TBL.tableID = "wiw_tbl" 
WIW_TBL.primaryKey = "PORTAL_USERID"
WIW_TBL.pkType = sa.types.String()

LOCATIONS_TBL.tableID = "locations_tbl"
LOCATIONS_TBL.primaryKey = "LOCATION_CODE"
LOCATIONS_TBL.pkType = sa.types.Integer()

tableList = ([开发者_StackOverflow社区WIW_TBL, LOCATIONS_TBL])

for i in tableList:

    i.tableID = sa.Table(i.tableID.upper(), meta.metadata,
    sa.Column(i.primaryKey, i.pkType, primary_key=True),
    autoload=True,
    autoload_with=engine) 

    orm.mapper(i.mappedClass, i.tableID)

The error that this code returns is:

sqlalchemy.exc.ArgumentError: Class '<class 'changeofname.model.mappedClass'>' already has a primary mapper defined. Use non_primary=True to create a non primary Mapper.  clear_mappers() will remove *all* current mappers from all classes.

I cant use clear_mappers as it wipes all of the classes and the entity_name scheme doesn't seem to apply here.

It seems that every object wants to use the same class, although they all should have their own instance of it.

Does anyone have any ideas?


Well, in your case it *is the same Class you try to map to different Tables. To solve this, create a class dynamically for each Table:

class Table(object):
    tableID = ''
    primaryKey = ''
    pkType = sa.types.String()
    def __init__(self):
        self.mappedClass = type('TempClass', (object,), {})

But I would prefer slightly cleaner version:

class Table2(object):
    def __init__(self, table_id, pk_name, pk_type):
        self.tableID = table_id
        self.primaryKey = pk_name
        self.pkType = pk_type
        self.mappedClass = type('Class_' + self.tableID, (object,), {})
# ...
WIW_TBL = Table2("wiw_tbl", "PORTAL_USERID", sa.types.String())
LOCATIONS_TBL = Table2("locations_tbl", "LOCATION_CODE", sa.types.Integer())
0

精彩评论

暂无评论...
验证码 换一张
取 消