2017-02-21 91 views
1

我有一個項目,我想所以我創建一個模塊引擎的自定義創建的SQLAlchemy

db_initializer.py到DB初始化(SQLAlchemy中)與其他模塊隔離:

engine = create_engine('sqlite:///db') # TODO from config file 
Session = sessionmaker(bind=engine) 
Base = declarative_base(bind=engine) 


def create_tables(): 
    Base.metadata.create_all(engine) 

首先我需要將create_all放入函數中,因爲我的模型位於另一個包中。

model/foo.py

from core.db_initializer import Base 

class User(Base): 
    __tablename__ = 'user' 

    id = Column(Integer, primary_key=True) 
    name = Column(String) 

    def __init__(self, name: str = None): 
     self.name = name 

    def __repr__(self): 
     return "<User(id=%d, name=%s)>" % (int(self.id), str(self.name)) 

而我的主要電話create_tables。

有沒有其他的辦法呢?現在我需要使用自定義配置(IP,User,...)創建引擎,只有主腳本知道可能的配置。

喜歡的東西

main.py

import db_initializer as db 
import model.foo 
db.init(config) # which create the engine and create table 

當我做這樣的事情我還沒有綁定到尚未創建發動機基本對象有問題。任何解決方案

回答

1

在聲明模型之前,您不需要創建引擎或會話。您可以在model/foo.py中聲明模型:

from sqlalchemy.ext.declarative import declarative_base 

Base = declarative_base() 

class User(Base): 
    __tablename__ = 'user' 

讓我們假設您在myapp.py中有一些應用程序。聲明它,所以它可以與發動機進行初始化:

from sqlalchemy.orm import Session 
import model.foo 

class MyApp: 
    def __init__(self, engine): 
     self.engine = engine 

    def get_users(self): 
     session = Session(self.engine) 
     users = session.query(model.foo.User).all() 
     session.close() 

     return users 

在main.py創建引擎,並用它來初始化models.foo.Base.metadata和其他應用程序在你需要它:

from sqlalchemy import create_engine 
import model.foo 
import myapp 

engine = create_engine('sqlite:///db') 

model.foo.Base.metadata.bind = engine 
model.foo.Base.metadata.create_all() 

app = myapp.MyApp(engine) 

UPD:對於scoped_session方法myapp.py可以看起來像這樣:

import model.foo 

class MyApp: 
    def __init__(self, session): 
     self.session = session 

    def get_users(self): 
     return self.session.query(model.foo.User).all() 

and main.py:

from sqlalchemy import create_engine 
from sqlalchemy.orm import sessionmaker, scoped_session 
import model.foo 
import myapp 

engine = create_engine('sqlite:///db') 
session = scoped_session(sessionmaker(engine)) 

model.foo.Base.metadata.bind = engine 
model.foo.Base.metadata.create_all() 

app = myapp.MyApp(session) 
+0

當你有很多模型時你將如何處理?如果我在__init__.py中定義Base,並在所有子模塊中使用它,那是一種很好的做法嗎? – Timo

+0

@Timo如果你有幾個文件中的模型,你可以在單獨的模塊模型/ base.py中聲明'Base',然後將它導入到model/foo.py,model/bar.py,main.py等。需要在初始化時定義它,創建引擎時只使用它的'metadata'。 –

+0

謝謝!但是最後一個問題如果你想使用scoped_session和sessionmaker,怎麼辦? – Timo