【发布时间】:2018-03-14 23:51:03
【问题描述】:
遇到一些人,希望能得到一些想法/帮助。
我有一个具有树结构的数据库,其中叶子可以作为外键参与多个父级。典型的例子是一个城市,它属于国家,属于大陆。不用说国家和大陆不应该是可重复的,因此在添加另一个城市之前,我需要在数据库中找到一个对象。如果它不存在,我必须创建它,但是如果国家不存在,那么我必须检查大陆,如果这个大陆不存在,那么我必须有它的创建过程。
到目前为止,如果我从单个文件运行它,我已经创建了一大堆项目,但是如果我将 SQL 炼金术代码推送到模块中,故事就会变得不同。由于某种原因,元范围变得有限,并且如果该表尚不存在,那么如果我查询外键是否存在(来自国家/地区的城市),则代码开始抛出 ProgrammingError 异常。我已经拦截了它,并且在我正在寻找的类的__init__ 类构造函数中(国家),我正在检查表是否存在,如果不存在则创建它。我有两件事有问题,需要关于以下方面的建议:
1) 表的验证效率低下 - 我正在使用 Base.metadata.sorted_tables 数组,我必须通过它查看并确定表结构是否与我的类 __tablename__ 匹配。如:
for table in Base.metadata.sorted_tables:
# Find a right table in the list of tables
if table.name == self.__tablename__:
if __DEBUG__:
print 'DEBUG: Found table {} that equal to the class table {}'.format(table.name, self.__tablename__)
if not table.exists():
session.get_bind().execute(table.create())
不用说,这需要时间,我正在寻找更有效的方法来做同样的事情。
2) 第二个问题是关于 Python 中 OOP 的声明性基 (declarative_base()) 的继承。我想去掉一些重复的代码并将它们拉入一个类,其他类将从该类派生。例如,上面的代码可以取出到单独的函数中,并具有如下内容:
Base = declarative_base()
class OnDemandTables(Base):
__tablename__ = 'no_table'
# id = Column(Integer, Sequence('id'), nullable=False, unique=True, primary_key=True, autoincrement=True)
def create_my_table(self, session):
if __DEBUG__:
print 'DEBUG: Creating tables for the class {}'.format(self.__class__)
print 'DEBUG: Base.metadata.sorted_tables exists returns {}'.format(Base.metadata.sorted_tables)
for table in Base.metadata.sorted_tables:
# Find a right table in the list of tables
if table.name == self.__tablename__:
if __DEBUG__:
print 'DEBUG: Found table {} that equal to the class table {}'.format(table.name, self.__tablename__)
if not table.exists():
session.get_bind().execute(table.create())
class Continent(OnDemandTables):
__tablename__ = 'continent'
id = Column(Integer, Sequence('id'), nullable=False, unique=True, primary_key=True, autoincrement=True)
name = Column(String(64), unique=True, nullable=False)
def __init__(self, session, continent_description):
if type(continent_description) != dict:
raise AttributeError('Continent should be described by the dictionary!')
else:
self.create_my_table(session)
if 'continent' not in continent_description:
raise ReferenceError('No continent can be created without a name!. Dictionary is {}'.
format(continent_description))
else:
self.name = continent_description['continent']
print 'DEBUG: Continent name is {} '.format(self.name)
这里的问题是元数据试图将不相关的类链接在一起,并且需要 __tablename__ 和一些索引列存在于父类 OnDemandTables 中,这对我来说没有任何意义。
有什么想法吗? 干杯
【问题讨论】:
标签: python sqlalchemy