SQLAlchemy在一个文件中使用两个不同的模型创建两个数据库

时间:2013-05-11 14:51:38

标签: python sqlalchemy

我想在database.py文件中初始化两个具有完全不同模型的数据库。

database.py

engine1 = create_engine(uri1)
engine2 = create_engine(uri2)

session1 = scoped_session(sessionmaker(autocommit=False,autoflush=False,bind=engine1))
session2 = scoped_session(sessionmaker(autocommit=False,autoflush=False,bind=engine2))

Base = declarative_base(name='Base')
Base.query = session1.query_property()

LogBase = declarative_base(name='LogBase')
LogBase.query = session2.query_property()

和两个模型结构:

models.py

class MyModel(Base):
    pass

models2.py

class MyOtherModel(LogBase):
    pass

回到database.py,我想在导入模型后创建/初始化数据库

# this does init the database correctly
def init_db1():
    import models
    Base.metadata.create_all(bind=engine1)

# this init function doeas not work properly
def init_db2():
    import models2
    LogBase.metadata.create_all(bind=engine2)

如果我在第二个init函数中更改导入它确实有效

def init_db2():
    from models2 import *
    LogBase.metadata.create_all(bind=engine2)

但有警告:

  

database.py:87:SyntaxWarninyntaxWarning:import *仅允许在模块级别

Everthing工作正常,我已初始化数据库,但警告告诉我,它有问题。

如果有人能解释为什么第一次尝试不正确,我将不胜感激。感谢。

1 个答案:

答案 0 :(得分:2)

您确实不鼓励在函数内部使用from ... import *语法,因为这使得Python无法确定该函数的本地名称,从而破坏了作用域规则。为了让Python无论如何都要工作,必须禁用某些优化,结果名称查找速度要慢得多。

否则我无法重现您的问题。仅导入models2可确保执行该模块中定义的所有内容,以便LogBase类具有所有声明的注册表。 models.py Base的{​​{1}}声明有效时,该路径没有理由失败。

出于SQLAlchemy和声明性表元数据的目的,import models2from models2 import *语法之间存在差异;只有它们对本地命名空间的影响不同。在两个情况下,运行models2顶级代码,定义类等,但在后一种情况下,模块中的顶级名称将添加到本地名称空间作为直接引用,而不仅仅是对要添加的模块对象的引用。