sqlalchemy 0.6 访问旧版数据库的方法?
我觉得这个应该很简单,但我找不到任何一个例子来说明怎么做。
举个例子,我有以下现有的表:
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的例子,但我真的不喜欢它通过不断调用数据库对象来访问数据库的方式。我按照文档里的数据库反射部分做到了这一步:
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的映射功能,这样我就可以构建事件对象并插入到数据库里。
我看了一下sqlsoup的内容:
from sqlalchemy.ext.sqlsoup import SqlSoup
db = SqlSoup(engine)
db.sources.all() #this kinda works out bet
但我不知道从这个点开始怎么添加对象。我甚至不确定这是不是我想要的,我希望能跟着教程和声明基础的内容走。有没有可能不需要重写一个类来建模整个表结构?如果不行,有人能告诉我在这个例子中该怎么做吗?
能不能给我指条明路,让我知道怎么让映射功能工作?
1 个回答
2
你可以通过把一个预定义的、自动加载的表赋值给 __table__ 属性,来使用 declarative_base。这样的话,表里的列会被自动识别出来,但你还是需要自己声明想要使用的关系。
class Source(Base):
__table__ = source
class Event(Base):
__table__ = event
source = relation(Source)
不过,如果你要插入大量的数据行,绕过 ORM 直接使用 executemany 会让性能大幅提升。你可以这样使用 executemany:
conn = engine.connect()
conn.execute(event.insert(),[
{'source_id': 1, 'info': 'xyz', 'item': 'foo'},
{'source_id': 1, 'info': 'xyz', 'item': 'bar'},
...
])