问题描述
我使用 sqlalchemy
的 ORM 库与我们应用程序的数据库之一进行交互。在一台主机上,应用实例的数据库后端是 Postgresql,而在另一台主机上,由于历史原因,我们使用 MysqL。
两个后端的模式(和关系)是相同的,但是 Postgresql 中的表和列名称是小写的,而在 MysqL 中它们是大写的。有什么方法可以在 sqlalchemy
中调整我的架构,这样我就不需要重复代码吗?
以下是我的架构示例。提示,该应用程序是 Confluence wiki ;)
from sqlalchemy import (
BigInteger,Column,DateTime,String,)
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Space(Base):
__tablename__ = 'spaces'
spaceid = Column(BigInteger,primary_key=True)
spacename = Column(String(255))
spacekey = Column(String(255),nullable=False,unique=True)
lowerspacekey = Column(String(255),index=True)
spacedescid = Column(BigInteger,index=True)
homepage = Column(BigInteger,index=True)
creator = Column(String(255),index=True)
creationdate = Column(DateTime,index=True)
lastmodifier = Column(String(255),index=True)
lastmoddate = Column(DateTime)
spacetype = Column(String(255))
spacestatus = Column(String(255),index=True)
解决方法
感谢@rfkortekaas 的建议,我设法通过自动映射架构并随后覆盖表名和列名的命名方案来解决该问题。
sqlalchemy
的文档有两个非常有用的页面:
为了后代:
from sqlalchemy import event
from sqlalchemy.ext.automap import automap_base
from .utilities import to_pascal_case,to_snake_case
AutomapBase = automap_base()
@event.listens_for(AutomapBase.metadata,"column_reflect")
def column_reflect(inspector,table,column_info):
column_info['key'] = to_snake_case(column_info['name'])
def classname_for_table(base,table_name,table):
return to_pascal_case(table_name)
if __name__ == '__main__':
dbcs = 'postgresql://username:password@127.0.0.1:3306/database'
automap_engine = create_engine(dbcs,future=True,echo=verbose > 2)
AutomapBase.prepare(
autoload_with=automap_engine,classname_for_table=classname_for_table,)
# Access the automapped classes with AutomapBase.classes.<class_name>