sqlalchemy 0.6 访问旧版数据库的方法?

0 投票
1 回答
1323 浏览
提问于 2025-04-15 19:25

我觉得这个应该很简单,但我找不到任何一个例子来说明怎么做。

举个例子,我有以下现有的表:

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'},
    ...
])

撰写回答