1

I want to initialize two databases with total different models in my database.py file.

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()

and the two model structures:

models.py

class MyModel(Base):
    pass

models2.py

class MyOtherModel(LogBase):
    pass

back to the database.py where i want to create/initialize the databases after importing the models

# 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)

if I change the import in the second init function it does work

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

but there is a warning:

database.py:87: SyntaxWarninyntaxWarning: import * only allowed at module level

Everthing does work properly, I have the databases initialized, but the Warning tells me, that there is something wrong with it.

If someone can explain me why the first attempt isn't correct I would be grateful. Thanks.

1 Answer 1

2

You are indeed discouraged from using the from ... import * syntax inside functions, because that makes it impossible for Python to determine what the local names are for that function, breaking scoping rules. In order for Python to make things work anyway, certain optimizations have to be disabled and name lookup is a lot slower as a result.

I cannot reproduce your problem otherwise. Importing just models2 makes sure that everything defined in that module is executed so that the LogBase class has a registry of all declarations. There is no reason for that path to fail while the models.py declarations for Base do work.

For the purposes of SQLAlchemy and declarative table metadata, there is no difference between the import models2 and the from models2 import * syntax; only their effect on the local namespace differs. In both cases, the models2 top-level code is run, classes are defined, etc. but in the latter case then the top-level names from the module are added to the local namespace as direct references, as opposed to just a reference to the module object being added.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the insight, but the main problem does exist: only from models2 import * does work, import model2 not and I cant get the reason. Are there any infos which could be interesting?
Sounds as if LogBase in the import models2 case is not the base actually used in models2. Does from models2 import LogBase work?
from models2 import LogBase actually works without any warnings! In models2 I import from database import LogBase so I thought that the LogBase should be the same. Thanks :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.