2016-10-10 135 views
4

我正在使用SQLAlchmey作为一个python项目的ORM。我创建了几个模型/架构,它工作正常。现在我需要查询一个现有的mysql数据库,不需要插入/更新select语句。sqlalchemy现有数据库查询

我怎样才能创建这个现有数据库的表周围的包装?我已经简要地浏览了sqlalchemy文档,但是却找不到任何相关的东西。所有建议执行方法,我需要写入原始SQL查询,虽然我想使用SQLAlchmey查询方法与我正在使用SA模型相同的方式。

例如,如果现有的数据库具有表名用户,然后我想用dbsession进行查询(只有选择操作,可能与加入)

+0

你最好使用[反射](http://docs.sqlalchemy.org/en/latest/core/reflection.html),和[automap](http://docs.sqlalchemy.org/en/latest/orm/extensions/automap.html),如果你想使用映射类。 –

回答

3

你似乎有印象的SQLAlchemy只能与工作由SQLAlchemy创建的数据库结构(可能使用MetaData.create_all()) - 这是不正确的。 SQLAlchemy可以与预先存在的数据库完美协作,您只需定义模型以匹配数据库表。要做到这一点的方法之一是使用反射,如ILJAEverilä提示:

class MyClass(Base): 
    __table__ = Table('mytable', Base.metadata, 
        autoload=True, autoload_with=some_engine) 

(在我看来,将是一次性的脚本完全正常,但可能会导致非常令人沮丧的错误在“真实”应用程序,如果有一个潜在的数据库结构,可随时间变化)

另一种方法是简单地定义你的模型像往常一样照顾来定义你的模型相匹配的数据库表,这并不难。这种方法的好处是,您只能将一部分数据库表映射到您的模型,甚至只能将一部分表列添加到模型的字段中。假设你在数据库中有10张表,但是从那里你只需要idname只关心users表和email领域:

class User(Base): 
    id = sa.Column(sa.Integer, primary_key=True) 
    name = sa.Column(sa.String) 
    email = sa.Column(sa.String) 

(注意,我们怎么也没有需要定义的一些细节时,才需要到发出正确的DDL,例如字符串字段的长度或email字段具有索引的事实)

除非您在代码中创建或修改模型,否则SQLAlchemy不会发出INSERT/UPDATE查询。如果你想确保你的查询是只读的,你可以在数据库中创建一个特殊的用户,并授予该用户SELECT权限。另外/另外,您也可以尝试回滚应用程序代码中的事务。

+0

谢谢,虽然我用反射automap,但你的建议也看起来不错。对于SO用户,如果您有时间,可以添加Automap的一个示例。这将使这个答案完成 – DevC

+0

@DevC:谢谢,我已经添加了一个例子 – Sergey

0

可以用下面的代码访问现有的表:

from sqlalchemy.orm import Session 

Base = automap_base() 
Base.prepare(engine, reflect=True) 
Users = Base.classes.users 
session = Session(engine) 
res = session.query(Users).first()