Python 2.7 基于表库动态创建sqlAlchemy元类

Python 2.7 基于表库动态创建sqlAlchemy元类,python-2.7,sqlalchemy,metaclass,Python 2.7,Sqlalchemy,Metaclass,我们在ERP系统中有几个客户。每个客户端都有自己的数据库。数据库在模式方面是相同的 不要问我为什么,但ERP db没有正式定义PKs,因此不可能反映数据库。。。相反,我们发现声明一个元类、一个表声明、详细说明PK和自动加载是有效的。例如: class Customers(Base): __table__ = Table('Customers', Base.metadata, Column('UniqueNo', Integer, primar

我们在ERP系统中有几个客户。每个客户端都有自己的数据库。数据库在模式方面是相同的

不要问我为什么,但ERP db没有正式定义PKs,因此不可能反映数据库。。。相反,我们发现声明一个元类、一个表声明、详细说明PK和自动加载是有效的。例如:

class Customers(Base):

    __table__ = Table('Customers', Base.metadata,
                      Column('UniqueNo', Integer, primary_key=True),
                      schema = 'databaseName.schema',
                      autoload = True
schema=
部分上有一个快速not。每个数据库的模式都是相同的,但是模式的命名(以及数据库名称本身)是不同的。像这样在元类中定义模式,使我们能够跨数据库查询ACC,从而能够

创建代码结构时,进行元类声明的最简单方法是手动。为每个数据库创建一个.py文件,并在每个文件中执行相同的元类声明,只更改模式,并在类名中添加后缀以避免命名混乱。像这样:

client1.py

class Customers_1(Base):

    __table__ = Table('Customers', Base.metadata,
                      Column('UniqueNo', Integer, primary_key=True),
                      schema = 'Dbclient1.client1Schema',
                      autoload = True
client2.py

class Customers_2(Base):

    __table__ = Table('Customers', Base.metadata,
                      Column('UniqueNo', Integer, primary_key=True),
                      schema = 'Dbclient2.client2Schema',
                      autoload = True
这样做是可行的,但我们希望通过仅基于一个ERPTables.py文件动态创建元类来减少代码量。例如:

ERPTables.py 

class Customers(Base):

    __table__ = Table('Customers', Base.metadata,
                      Column('UniqueNo', Integer, primary_key=True),
                      autoload = True
这引导我们走上元类的道路,这是一个陌生的领域。我已经到了能够动态创建元类声明的地步。但是:注册声明是我理解的不足之处。我已经走了这么远:

from sqlalchemy import Table
import ERPTables
import inspect

def iterate_ERPTables_Tables():
    for table in inspect.getmembers(ERPTables):
        if isinstance(table[1], Table) :
            return table[0], table[1]


dbSchemas = {'_1': 'Dbclient1.client1Schema', '_2': 'Dbclient2.client2Schema'}

 tables = [iterate_TableTest_Tables()]

 for key in dbSchemas:

    for table in tables:

          cls = type(table[0] + key, (Base, ), {'__tablename__': table[0], '__table__': table[1]})        

          break
这个代码有效!唯一的问题是SA元类被命名为cls。因此,
中断
。如果没有它,我们将试图声明几个具有相同类名的元类

我尝试了几种方法来解决这个问题,比如尝试使用不熟悉的元类透视图:

dbSchemas = {'_1': 'Dbclient1.client1Schema', '_2': 'Dbclient2.client2Schema'}

 tables = [iterate_TableTest_Tables()]

 for key in dbSchemas:

    for table in tables:

          type(table[0] + key, (Base, ), {'__tablename__': table[0], '__table__': table[1]}).__new__        
要全面解决黑客问题,请执行以下操作:

dbSchemas = {'_1': 'Dbclient1.client1Schema', '_2': 'Dbclient2.client2Schema'}

 tables = [iterate_TableTest_Tables()]

 for key in dbSchemas:

    for table in tables:

          exec("%s = %s" % (table[0] + key, type(table[0] + key, (Base, ), {'__tablename__': table[0], '__table__': table[1]})))
但是我所有的尝试都没有成功,因此,在最后一刻,我求助于so,希望有人能告诉我如何解决这个问题


PS:如果有人想知道,到目前为止,我还没有解决如何将
dbSchemas
dictionnary中的模式注入元类的问题。我希望找到一种方法,但每次只解决一个问题

如果要导出对类的引用,可以将它们添加到
globals()


谢谢你!这是一个有趣的答案,我正在把问题缩小到这个范围的路上。我写了[另一个问题](),被称为更一般的问题/观察。如果你能试着回答这个问题,那就太好了。既为了我自己,也为了其他读者。看来人们对这个问题很感兴趣。再次感谢你的帮助!
globals()[table[0] + key] = type(...)