2013-10-04 46 views
24

我無法使用SQLAlchemy創建單個表。如何用SQLAlchemy只創建一個表?

我可以通過調用Base.metadata.create_all(engine)來創建它,但隨着表的數量增加,此調用需要很長時間。

我創建表類,然後填充它們。

from sqlalchemy import create_engine, Column, Integer, Sequence, String, Date, Float, BIGINT 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy.orm import sessionmaker 

Base = declarative_base() 

class HistoricDay(): 

    id = Column(Integer, Sequence('id_seq'), primary_key=True) 
    # Date, Open, High, Low, Close, Volume, Adj Close 
    date = Column(Date) 
    open = Column(Float) 
    high = Column(Float) 
    low = Column(Float) 
    close = Column(Float) 
    volume = Column(BIGINT) 
    adjClose = Column(Float) 

    def __init__(self, date, open, high, low, close, volume, adjClose): 
     self.date = date 
     self.open = open 
     self.high = high 
     self.low = low 
     self.close = close 
     self.volume = volume 
     self.adjClose = adjClose 

def build_daily_history_table_repr(self): 
     return "<"+self.__tablename__+"('{}','{}','{}','{}','{}','{}','{}','{}')>".format(self.id, self.date, self.open, self.high, self.low, self.close, self.volume, self.adjClose) 

def build_daily_history_table(ticket): 
    classname = ticket+"_HistoricDay" 
    globals()[classname] = type(classname, (HistoricDay,Base), {'__tablename__' : ticket+"_daily_history"}) 
    setattr(globals()[classname], '__repr__', build_daily_history_table_repr) 

# Initialize the database :: Connection & Metadata retrieval 
engine = create_engine('mysql+cymysql://[email protected]/gwc?charset=utf8&use_unicode=0', pool_recycle=3600) # ,echo = True 

# SqlAlchemy :: Session setup 
Session = sessionmaker(bind=engine) 

# Create all tables that do not already exist 
Base.metadata.create_all(engine) 

# SqlAlchemy :: Starts a session 
session = Session() 

ticketList = getTicketList() 

for ticket in ticketList: 
    build_daily_history_table(ticket) 
    class_name = ticket+"_HistoricDay" 

    meta_create_all_timer = time.time() 
    # Create all tables that do not already exist 
    # globals()[class_name]('2005-07-24',0,0,0,0,0,0).create(engine) #doesn't work 
    #(globals()[class_name]).__table__.create(engine) #doesn't work 
    # session.commit() #doesn't work 

    #Base.metadata.create_all(engine) # works but gets very slow 
    print(" meta_create_all_timer {}s".format(time.time()-meta_create_all_timer)) 

    data = getData(ticket) 

    for m_date, m_open, m_close, m_high, m_low, m_volume, m_adjClose in data: 
     entry = globals()[class_name](m_date, m_open, m_high, m_low, m_close, m_volume, m_adjClose) 
     session.add(entry) 

    session.commit() 

我在documentation看到,你可以做

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

meta = MetaData() 

employees = Table('employees', meta, 
    Column('employee_id', Integer, primary_key=True), 
    Column('employee_name', String(60), nullable=False, key='name'), 
    Column('employee_dept', Integer, ForeignKey("departments.department_id")) 
) 
employees.create(engine) 

不過,我無法弄清楚如何做同樣的事情Table確實,與declarative_base()

我該怎麼做,繼承自declarative_base()的類?

+1

它應該是'HistoricDay(Base)' –

+0

否,因爲HistoricDay沒有屬性表名。 生成的類繼承自Base:globals()[classname] = type(classname,(HistoricDay,Base),{'tablename':ticket +「_ daily_history」}) – Lazik

回答

17

Above, the declarative_base() callable returns a new base class from which all mapped classes should inherit. When the class definition is completed, a new Table and mapper() will have been generated.

The resulting table and mapper are accessible via __table__ and __mapper__ attributes

(來自here

因此:

def build_daily_history_table(ticket): 
    classname = ticket + "_HistoricDay" 
    ticket = type(classname, (Base, HistoricDay), {'__tablename__' : ticket+"_daily_history"}) 
    ticket.__repr__ = build_daily_history_table_repr 
    return ticket 

build_daily_history_table("test").__table__.create(bind = engine) 

輸出:

2013-10-04 22:36:53,263 INFO sqlalchemy.engine.base.Engine 
CREATE TABLE test_daily_history (
    id INTEGER NOT NULL, 
    date DATE, 
    open FLOAT, 
    high FLOAT, 
    low FLOAT, 
    close FLOAT, 
    volume BIGINT, 
    "adjClose" FLOAT, 
    PRIMARY KEY (id) 
) 


2013-10-04 22:36:53,263 INFO sqlalchemy.engine.base.Engine() 
2013-10-04 22:36:53,263 INFO sqlalchemy.engine.base.Engine COMMIT 

幸得javex's評論/校正或I migh T的建議一個類似於:

Base.metadata.tables["ticket_daily_history"].create(bind = engine) 

提醒:

build_daily_history_table使用的可能是做的事情,主要是它污染/弄亂的原因中最優雅的方式之一方法namespace

+0

我試過,但是 'Traceback(最近一次調用最後一次) : 文件 「autoPopulate.py」,線路493,在 m_init() 文件 「autoPopulate.py」,線422,在m_init 狀態= success_state(票) 文件 「autoPopulate.py」,線306,在success_state 全局()[CLASS_NAME] .create(發動機) AttributeError的:對象類型 'HMN_HistoricDay' 沒有屬性「create'' – Lazik

+28

'HistoricDay .__表__創建(發動機)' – javex

+0

@javex 1良好抓 –

相關問題