sqlalchemy 0.6遗留数据库访问?

时间:2010-02-17 22:53:25

标签: python sqlalchemy legacy-database

我觉得这应该很简单,但是我找不到它的一个例子。

作为一个例子,我有以下现有表格:

CREATE TABLE `source` (
  `source_id` tinyint(3) unsigned NOT NULL auto_increment,
  `name` varchar(40) default NULL,
  PRIMARY KEY  (`source_id`),
  UNIQUE KEY `source_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

CREATE TABLE `event` (
  `source_id` tinyint(3) unsigned NOT NULL default '0',
  `info` varchar(255) NOT NULL default '',
  `item` varchar(100) NOT NULL default '',
  PRIMARY KEY  (`source_id`,`info`,`item`),
  KEY `event_fkindex1` (`source_id`),
  CONSTRAINT `event_fk1` FOREIGN KEY (`source_id`) REFERENCES `source` (`source_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

我想使用sqlalchemy 0.6将很多行添加到事件表中。我已经看到了一些sqlsoup示例,但真的很讨厌通过不断调用db对象来访问db的方式。我按照文档进行了数据库反射的内容,并且做到了这一点:

import sqlalchemy
from sqlalchemy import Table, Column, MetaData, create_engine
from sqlalchemy.orm import sessionmaker
engine = create_engine('mysql://user:pass@server/db', echo=True)
metadata = MetaData()
source = Table('source', metadata, autoload=True, autoload_with=engine)
Session = sessionmaker(bind=engine)
session = Session()
session.query(source).first()

这会返回一个非常丑陋的对象。我真的想要sqlalchemy ORM的映射器功能,所以我可以构造要插入数据库的Event对象。

我看了一下sqlsoup的东西:

from sqlalchemy.ext.sqlsoup import SqlSoup
db = SqlSoup(engine)
db.sources.all() #this kinda works out bet

但我无法弄清楚如何在这一点上添加对象。我甚至不确定这是我想要的,我希望能够遵循教程和declarative_base的东西。这是否可以在不必重写类来模拟整个表结构的情况下实现?如果不是,有人可以告诉我在这个例子中我是怎么做的吗?

有人能让我走上正确的道路,让映射器工作起作用吗?

1 个答案:

答案 0 :(得分:2)

您可以将预定义/自动加载的表与declarative_base一起使用,方法是将其分配给__table__属性。从表中选取列,但您仍然会声明要使用的任何关系。

class Source(Base):
    __table__ = source

class Event(Base):
    __table__ = event
    source = relation(Source)

但是如果你要插入大量的行,那么绕过ORM并使用executemany将会带来很大的性能提升。你可以像这样使用execute many:

conn = engine.connect()
conn.execute(event.insert(),[
    {'source_id': 1, 'info': 'xyz', 'item': 'foo'},
    {'source_id': 1, 'info': 'xyz', 'item': 'bar'},
    ...
])