1

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

数据库.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()

和两个模型结构:

模型.py

class MyModel(Base):
    pass

模型2.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)

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

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

但有一个警告:

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

一切正常,我已经初始化了数据库,但是警告告诉我,它有问题。

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

4

1 回答 1

2

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

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

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

于 2013-05-11T14:55:31.587 回答