我无法使用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://root@localhost/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)

然而,我不知道如何用declarative_base()Table的事情.

对于继承自declarative_base()的类,我如何做到这一点?

推荐答案

上面,声明性的_base()callable从

生成的表格和映射器可通过__table__

(从here开始)

Therefore:

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)

Output:

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条 comments /更正,否则我可能会提出类似的建议:

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

Advise:

build_daily_history_table中使用的方法可能是最不优雅的做事方式之一,主要原因是它污染了namespace人.

Mysql相关问答推荐

在MySQL中从非连续数据创建时间线

为什么我安装MySQL时不能使用3306端口?

为什么MySQL不考虑在联接中使用(JSON)函数索引,而考虑在生成的列上使用索引?

mysql 获取每个单词的第一个字母

SQL Select 最大值和平均值

GoRM中行最大值查询返回"0"

模拟Mysql Cursor类的fetchone()方法,并将其返回值设置为None

根据 JOIN 结果计算列中的值?

SQL查询以查找两个特定行的总和

在 where 子句中左连接多个值

在分组结果 MySQL 5.7 版中获取最多的重复值

使用 JOIN 计算列中的所有值

在 MySQL 中转换 JSON 数组值

计算每个用户在第二个表中有多少条记录

结果差异(MySQL 5.7 vs MySQL 8.0)

MySQL Workbench - 如何同步 EER 图

MySQL - 使一对值唯一

INSERT ... 使用 WHERE 进行重复的密钥更新?

在 MySQL 中找不到 outfile 创建的文件

MySQL:切换 int 字段值的简单方法