├── faq ├── index.html ├── metadata_schema.html └── sqlexpressions.html ├── core ├── expression_api.html ├── api_basics.html ├── types.html ├── serializer.html ├── engines_connections.html ├── index.html ├── schema.html └── inspection.html ├── orm ├── extending.html ├── extensions │ ├── index.html │ ├── declarative │ │ ├── index.html │ │ └── basic_use.html │ └── horizontal_shard.html ├── scalar_mapping.html ├── loading_objects.html ├── mapper_config.html ├── relationships.html ├── constructors.html ├── session.html ├── exceptions.html └── index.html ├── changelog └── index.html ├── dialects ├── sybase.html └── index.html └── intro.html /faq/index.html: -------------------------------------------------------------------------------- 1 |

常见问题

“常见问题”部分收集了大量常见问题和众所周知的问题。

-------------------------------------------------------------------------------- /core/expression_api.html: -------------------------------------------------------------------------------- 1 |

SQL语句和表达式API

本节介绍SQL表达式语言的API参考。有关其用法的完整介绍,请参阅SQL Expression Language Tutorial

-------------------------------------------------------------------------------- /orm/extending.html: -------------------------------------------------------------------------------- 1 |

事件和内部

-------------------------------------------------------------------------------- /orm/extensions/index.html: -------------------------------------------------------------------------------- 1 |

ORM扩展

SQLAlchemy提供了各种可用的ORM扩展,它们为核心行为增加了额外的功能。

扩展几乎完全基于公共核心和ORM API,应鼓励用户阅读其源代码以进一步理解其行为。特别是“水平分割”,“混合属性”和“突变跟踪”扩展非常简洁。

-------------------------------------------------------------------------------- /core/api_basics.html: -------------------------------------------------------------------------------- 1 |

核心API基础

-------------------------------------------------------------------------------- /core/types.html: -------------------------------------------------------------------------------- 1 |

列和数据类型

-------------------------------------------------------------------------------- /orm/scalar_mapping.html: -------------------------------------------------------------------------------- 1 |

映射列和表达式

以下各节讨论如何将表列和SQL表达式映射到单个对象属性。

-------------------------------------------------------------------------------- /orm/loading_objects.html: -------------------------------------------------------------------------------- 1 |

加载对象

有关映射对象的一般加载的注释和功能。

有关查询SQLAlchemy ORM的深入介绍,请参阅Object Relational Tutorial

-------------------------------------------------------------------------------- /changelog/index.html: -------------------------------------------------------------------------------- 1 |

变化和迁移

SQLAlchemy更新日志和迁移指南现在集成在主文档中。

当前的迁移指南

更改日志

旧版迁移指南

-------------------------------------------------------------------------------- /orm/mapper_config.html: -------------------------------------------------------------------------------- 1 |

映射器配置

本节介绍可用于映射器的各种配置模式。它假定你已经完成了Object Relational Tutorial并知道如何构建和使用基本的映射器和关系。

-------------------------------------------------------------------------------- /core/serializer.html: -------------------------------------------------------------------------------- 1 |

表达式串行器扩展

Serializer / Deserializer对象与SQLAlchemy查询结构一起使用,允许“上下文”反序列化。

任何基于sqlalchemy.sql的SQLAlchemy查询结构。*或sqlalchemy.orm。*可以使用。映射器,表格,列,会话等结构引用的内容不是以序列化形式持久化的,而是在反序列化时与查询结构重新关联。

用法与标准Python pickle模块的用法几乎相同:

from sqlalchemy.ext.serializer import loads, dumps
 2 | metadata = MetaData(bind=some_engine)
 3 | Session = scoped_session(sessionmaker())
 4 | 
 5 | # ... define mappers
 6 | 
 7 | query = Session.query(MyClass).
 8 |     filter(MyClass.somedata=='foo').order_by(MyClass.sortkey)
 9 | 
10 | # pickle the query
11 | serialized = dumps(query)
12 | 
13 | # unpickle.  Pass in metadata + scoped_session
14 | query2 = loads(serialized, metadata, Session)
15 | 
16 | print query2.all()

与使用生腌菜时类似的限制适用;映射类本身必须是可以选择的,这意味着它们可以从模块级命名空间导入。

序列化器模块仅适用于查询结构。它不需要:

sqlalchemy.ext.serializer.Serializer(*args, **kw)
sqlalchemy.ext.serializer.Deserializer(file, metadata=None, scoped_session=None, engine=None)
sqlalchemy.ext.serializer.dumps(obj, protocol=0)
sqlalchemy.ext.serializer.loads(data, metadata=None, scoped_session=None, engine=None)
-------------------------------------------------------------------------------- /core/engines_connections.html: -------------------------------------------------------------------------------- 1 |

引擎和连接使用

-------------------------------------------------------------------------------- /orm/extensions/declarative/index.html: -------------------------------------------------------------------------------- 1 |

声明¶ T0>

声明性系统是SQLAlchemy ORM提供的通常使用的系统,用于定义映射到关系数据库表的类。但是,正如Classical Mappings所述,Declarative实际上是一系列在SQLAlchemy mapper()结构之上的扩展。

虽然文档通常提到了大多数示例的声明,但以下各节将提供有关声明API如何与基本mapper()和Core Table系统交互的详细信息,如以及如何使用mixin等系统构建复杂模式。

-------------------------------------------------------------------------------- /orm/extensions/horizontal_shard.html: -------------------------------------------------------------------------------- 1 |

水平分片

水平分片支持。

定义了一个基本的“水平分割”系统,它允许会话跨多个数据库分发查询和持久性操作。

有关使用示例,请参阅源分布中包含的Horizontal Sharding示例。

API文档

class sqlalchemy.ext.horizontal_shard.ShardedSession(shard_chooser, id_chooser, query_chooser, shards=None, query_cls=<class 'sqlalchemy.ext.horizontal_shard.ShardedQuery'>, **kwargs)

基础:sqlalchemy.orm.session.Session

__init__(shard_chooser, id_chooser, query_chooser, shards=None, query_cls=<class 'sqlalchemy.ext.horizontal_shard.ShardedQuery'>, **kwargs)

构建ShardedSession。

参数:
  • shard_chooser – A callable which, passed a Mapper, a mapped instance, and possibly a SQL clause, returns a shard ID. 该ID可以基于对象内存在的属性或某种循环方案。如果该方案基于选择,则应设置实例上的任何状态以将其标记为参与该分片。
  • id_chooser – A callable, passed a query and a tuple of identity values, which should return a list of shard ids where the ID might reside. 数据库将按照此列表的顺序进行查询。
  • query_chooser – For a given Query, returns the list of shard_ids where the query should be issued. 所有返回的碎片结果将合并成一个列表。
  • shards – A dictionary of string shard names to Engine objects.
class sqlalchemy.ext.horizontal_shard.ShardedQuery(*args, **kwargs)

基础:sqlalchemy.orm.query.Query

set_shard T0> ( T1> shard_id T2> ) T3> ¶ T4>

返回一个新的查询,限于单个分片ID。

无论其他状态如何,返回查询的所有后续操作都将针对单个分片。

-------------------------------------------------------------------------------- /orm/relationships.html: -------------------------------------------------------------------------------- 1 |

关系配置

本节介绍relationship()函数并深入讨论其用法。有关关系的介绍,请从Object Relational Tutorial开始,然后进入Building a Relationship

-------------------------------------------------------------------------------- /dialects/sybase.html: -------------------------------------------------------------------------------- 1 |

的Sybase ¶ T0>

支持Sybase数据库。

DBAPI支持

以下dialect / DBAPI选项可用。请参阅各个DBAPI部分的连接信息。

注意

Sybase方言在当前的SQLAlchemy版本上运行,但没有经常测试,并且可能有许多问题和警告,目前尚未处理。

蟒-SYBASE ¶ T0>

通过Python-Sybase驱动程序支持Sybase数据库。

DBAPI ¶ T0>

Documentation and download information (if applicable) for Python-Sybase is available at: http://python-sybase.sourceforge.net/

连接¶ T0>

连接字符串:

sybase+pysybase://<username>:<password>@<dsn>/[database name]

Unicode支持

python-sybase驱动程序目前似乎不支持任何类型的非ASCII字符串。

pyodbc ¶ T0>

通过PyODBC驱动程序支持Sybase数据库。

DBAPI ¶ T0>

PyODBC的文档和下载信息(如果适用)可在以下网址获得:http://pypi.python.org/pypi/pyodbc/

连接¶ T0>

连接字符串:

sybase+pyodbc://<username>:<password>@<dsnname>[/<database>]

Unicode支持

pyodbc驱动程序当前支持使用Unicode或多字节字符串的这些Sybase类型:

CHAR
2 | NCHAR
3 | NVARCHAR
4 | TEXT
5 | VARCHAR

目前不支持的是:

UNICHAR
6 | UNITEXT
7 | UNIVARCHAR

mxodbc ¶ T0>

通过mxODBC驱动程序支持Sybase数据库。

DBAPI ¶ T0>

mxODBC的文档和下载信息(如果适用)可在以下网址获得:http://www.egenix.com/

连接¶ T0>

连接字符串:

sybase+mxodbc://<username>:<password>@<dsnname>

注意

这种方言只是一个存根,目前可能不起作用。

-------------------------------------------------------------------------------- /core/index.html: -------------------------------------------------------------------------------- 1 |

SQLAlchemy Core

The breadth of SQLAlchemy’s SQL rendering engine, DBAPI integration, transaction integration, and schema description services are documented here. 与ORM的以领域为中心的使用模式相反,SQL表达式语言提供了一个以模式为中心的使用范例。

-------------------------------------------------------------------------------- /dialects/index.html: -------------------------------------------------------------------------------- 1 |

方言¶ T0>

方言是SQLAlchemy用来与各种类型的DBAPI实现和数据库进行通信的系统。以下部分包含参考文档和特定于每个后端用法的注释,以及各种DBAPI的注释。

所有方言都要求安装适当的DBAPI驱动程序。

包含的方言

外部方言

在版本0.8中更改:从SQLAlchemy 0.8开始,几种方言已移至外部项目,新数据库的方言也将作为外部项目发布。这里的基本原理是保持基本的SQLAlchemy安装和测试套件的增长非常大。

诸如SQLite,MySQL,Postgresql,Oracle,SQL Server和Firebird等“经典”方言目前仍将保留在Core中。

在版本1.0中更改: Drizzle方言已被移入第三方系统。

当前SQLAlchemy的外部方言项目包括:

生产就绪

实验/不完整

处于不完整状态或被认为有点实验性的方言。

阁楼¶ T0>

“阁楼”中的方言是早些时候为SQLAlchemy贡献的,但自那时以来很少受到关注或需求,现在迁移到自己的仓库中,最多只是半工作状态。对这些方言感兴趣的社区成员应该可以自由选择他们当前的代码库,并转入工作库。

-------------------------------------------------------------------------------- /orm/constructors.html: -------------------------------------------------------------------------------- 1 |

构造函数和对象初始化

映射不会对该类的构造函数(__init__)方法施加任何限制或要求。您可以自由地为您希望的函数请求任何参数,为ORM未知的实例分配属性,并且通常在编写Python类的构造函数时执行通常要做的任何其他操作。

当从数据库行重新创建对象时,SQLAlchemy ORM不会调用__init__ORM的过程有点类似于Python标准库的pickle模块,调用低级别的__new__方法,然后直接在实例上静静地恢复属性,而不是调用__init__

如果您需要在数据库加载的实例准备就绪之前对其进行设置,那么可以使用@reconstructor修饰器将方法标记为__init__每次加载或重建实例时,SQLAlchemy都会在没有参数的情况下调用此方法。这对于重新创建通常在__init__中分配的瞬态属性非常有用:

from sqlalchemy import orm
 2 | 
 3 | class MyMappedClass(object):
 4 |     def __init__(self, data):
 5 |         self.data = data
 6 |         # we need stuff on all instances, but not in the database.
 7 |         self.stuff = []
 8 | 
 9 |     @orm.reconstructor
10 |     def init_on_load(self):
11 |         self.stuff = []

在执行obj = MyMappedClass()时,Python将__init__ normal和data参数是必需的。当像query(MyMappedClass).one()那样在Query操作期间加载实例时,会调用init_on_load

任何方法都可以标记为reconstructor(),甚至可以标记为__init__方法。SQLAlchemy将调用没有参数的重构器方法。该实例的标量(非集合)数据库映射属性将可用于该函数中。急切加载的集合通常还不可用,通常只包含第一个元素。在此阶段对对象所做的ORM状态更改将不会记录下一次flush()操作,因此重构器中的活动应保守。

reconstructor()是一个更大的“实例级”事件系统的快捷方式,可以使用事件API进行订阅 - 请参阅InstanceEvents事件。

sqlalchemy.orm。 T0> 重建 T1> ( T2> FN T3> ) T4> ¶ T5 >

装饰方法作为'重建'钩子。

Designates a method as the “reconstructor”, an __init__-like method that will be called by the ORM after the instance has been loaded from the database or otherwise reconstituted.

重构器将被调用,不带任何参数。该实例的标量(非集合)数据库映射属性将可用于该函数中。急切加载的集合通常还不可用,通常只包含第一个元素。在此阶段对对象所做的ORM状态更改将不会记录下一次flush()操作,因此重构器中的活动应保守。

-------------------------------------------------------------------------------- /orm/session.html: -------------------------------------------------------------------------------- 1 |

使用会话

orm.mapper()函数和declarative扩展是ORM的主要配置接口。一旦配置了映射,持久化操作的主要用法界面就是Session

-------------------------------------------------------------------------------- /core/schema.html: -------------------------------------------------------------------------------- 1 |

模式定义语言

本节引用描述和检查数据库模式的全面系统SQLAlchemy 模式元数据

SQLAlchemy的查询和对象映射操作的核心由数据库元数据支持,它由描述表和其他模式级对象的Python对象组成。这些对象是三种主要操作类型的核心 - 发出CREATE和DROP语句(称为DDL),构建SQL查询以及表达关于数据库中已存在的结构的信息。

数据库元数据可以通过使用诸如TableColumnForeignKeySequence,所有这些都是从sqlalchemy.schema包导入的。它也可以由SQLAlchemy使用名为reflection的进程生成,这意味着您从一个对象(如Table)开始,为其指定一个名称,然后指示SQLAlchemy加载与特定发动机源相关的所有附加信息。

SQLAlchemy的数据库元数据结构的一个关键特性是它们被设计成用于与真实DDL非常相似的声明式风格。因此,对于那些在创建真正的模式生成脚本方面有一定背景的人来说,他们最直观。

-------------------------------------------------------------------------------- /orm/exceptions.html: -------------------------------------------------------------------------------- 1 |

ORM异常

SQLAlchemy ORM异常。

sqlalchemy.orm.exc。 T0> ConcurrentModificationError T1> ¶ T2>

StaleDataError的别名

异常 sqlalchemy.orm.exc。 DetachedInstanceError

尝试访问分离的映射实例上的卸载属性。

异常 sqlalchemy.orm.exc。 FlushError

flush()期间检测到无效条件。

异常 sqlalchemy.orm.exc。 MultipleResultsFound

单个数据库结果是必需的,但不止一个被发现。

sqlalchemy.orm.exc.NO_STATE = (<type 'exceptions.AttributeError'>, <type 'exceptions.KeyError'>)

工具实现可能引发的异常类型。

异常 sqlalchemy.orm.exc。 NoResultFound

数据库结果是必需的,但没有找到。

异常 sqlalchemy.orm.exc。 ObjectDeletedError 状态msg =无 T5> ) T6> ¶ T7>

刷新操作无法检索与对象的已知主键标识相对应的数据库行。

刷新操作在对象上访问过期属性或使用Query.get()检索检索到的对象时检测为过期。基于主键为目标行发出SELECT;如果没有行被返回,则引发此异常。

这个异常的真正含义就是,不存在与持久对象关联的主键标识符的行。该行可能已被删除,或者在某些情况下主键已更新为新值,而不在ORM的目标对象管理之外。

异常 sqlalchemy.orm.exc。 ObjectDereferencedError

由于垃圾收集对象,操作无法完成。

异常 sqlalchemy.orm.exc。 StaleDataError

遇到数据库状态的操作未被记录。

导致这种情况发生的条件包括:

异常 sqlalchemy.orm.exc。 UnmappedClassError clsmsg =无 T5> ) T6> ¶ T7>

为未知类别请求映射操作。

异常 sqlalchemy.orm.exc。 UnmappedColumnError

在未知列上请求映射操作。

异常 sqlalchemy.orm.exc。 UnmappedError

基础包含预期映射不存在的异常。

异常 sqlalchemy.orm.exc。 UnmappedInstanceError objmsg =无 T5> ) T6> ¶ T7>

为未知实例请求映射操作。

-------------------------------------------------------------------------------- /orm/index.html: -------------------------------------------------------------------------------- 1 |

SQLAlchemy ORM

这里介绍并充分描述了对象关系映射器。如果您想使用为您自动构建的高级SQL以及Python对象的自动持久性,请首先阅读本教程。

-------------------------------------------------------------------------------- /core/inspection.html: -------------------------------------------------------------------------------- 1 |

运行时检测API

检查模块提供了inspect()函数,该函数在Core和ORM中传递有关各种SQLAlchemy对象的运行时信息。

inspect()函数是SQLAlchemy的公共API的入口点,用于查看内存中对象的配置和构造。根据传递给inspect()的对象的类型,返回值可以是提供已知接口的相关对象,或者在许多情况下它将返回对象本身。

inspect()的基本原理是双重的。One is that it replaces the need to be aware of a large variety of “information getting” functions in SQLAlchemy, such as Inspector.from_engine(), orm.attributes.instance_state(), orm.class_mapper(), and others. 另一个原因是,inspect()的返回值保证服从一个记录的API,因此允许构建在SQLAlchemy配置之上的第三方工具以前向兼容的方式构建。

0.8版中的新功能从版本0.8开始引入inspect()系统。

sqlalchemy.inspection.inspect(subject, raiseerr=True)

为给定的目标生成检查对象。

在某些情况下,返回的值可能与给定的对象相同,例如传递Mapper对象。在其他情况下,它将是给定对象的注册检查类型的实例,例如,如果传递engine.Engine,则返回一个Inspector对象。

参数:
  • subject – the subject to be inspected.
  • raiseerr – When True, if the given subject does not correspond to a known SQLAlchemy inspected type, sqlalchemy.exc.NoInspectionAvailable is raised. 如果False,则返回None

可用的检查目标

以下列出了许多最常见的检查目标。

-------------------------------------------------------------------------------- /faq/metadata_schema.html: -------------------------------------------------------------------------------- 1 |

MetaData / Schema

当我说table.drop() / metadata.drop_all() 时,

这通常对应于两个条件:1.使用对表锁确实严格的PostgreSQL,以及2.您的连接仍处于打开状态,其中包含表中的锁,并且与用于DROP语句的连接不同。下面是最小版本的模式:

connection = engine.connect()
 2 | result = connection.execute(mytable.select())
 3 | 
 4 | mytable.drop(engine)

以上,连接池连接仍被检出;此外,上面的结果对象还保持与此连接的链接。如果使用“隐式执行”,则结果将保持此连接处于打开状态,直到结果对象关闭或所有行耗尽。

mytable.drop(engine)的调用会尝试在从Engine采购的第二个连接上发出DROP TABLE,该连接将被锁定。

解决方法是在发出DROP TABLE之前关闭所有连接:

connection = engine.connect()
 5 | result = connection.execute(mytable.select())
 6 | 
 7 | # fully read result sets
 8 | result.fetchall()
 9 | 
10 | # close connections
11 | connection.close()
12 | 
13 | # now locks are removed
14 | mytable.drop(engine)

SQLAlchemy是否支持ALTER TABLE,CREATE VIEW,CREATE TRIGGER,架构升级功能?

一般ALTER支持不直接出现在SQLAlchemy中。对于特殊的DDL,可以使用DDL和相关的结构。有关此主题的讨论,请参阅core_ddl

更全面的选择是使用模式迁移工具,例如Alembic或SQLAlchemy-Migrate;请参阅Altering Schemas through Migrations以便进行讨论。

我如何按照依赖关系的顺序对Table对象进行排序?

这可以通过MetaData.sorted_tables函数使用:

metadata = MetaData()
15 | # ... add Table objects to metadata
16 | ti = metadata.sorted_tables:
17 | for t in ti:
18 |     print(t)

我怎样才能将CREATE TABLE / DROP TABLE输出作为字符串?

现代SQLAlchemy具有代表DDL操作的子句结构。这些可以像任何其他SQL表达式一样呈现为字符串:

from sqlalchemy.schema import CreateTable
19 | 
20 | print(CreateTable(mytable))

要获取特定于某个引擎的字符串:

print(CreateTable(mytable).compile(engine))

还有一种特殊的Engine形式,可以让您使用以下配方转储整个元数据创建序列:

def dump(sql, *multiparams, **params):
21 |     print(sql.compile(dialect=engine.dialect))
22 | engine = create_engine('postgresql://', strategy='mock', executor=dump)
23 | metadata.create_all(engine, checkfirst=False)

Alembic工具还支持“离线”SQL生成模式,可将数据库迁移呈现为SQL脚本。

我怎么可以继承Table / Column来提供某些行为/配置?

TableColumn不适合直接子类化。但是,有一些简单的方法可以使用创建函数获取构建行为,以及与模式对象之间的关联有关的行为,例如约束约定或使用附件事件的命名约定。命名约定中可以看到许多这些技术的一个例子。

-------------------------------------------------------------------------------- /orm/extensions/declarative/basic_use.html: -------------------------------------------------------------------------------- 1 |

基本使用

SQLAlchemy对象关系配置涉及Tablemapper()和类对象的组合以定义映射类。declarative allows all three to be expressed at once within the class declaration. 尽可能使用常规SQLAlchemy模式和ORM结构,因此“古典”ORM使用和声明性之间的配置保持高度相似。

举一个简单的例子:

from sqlalchemy.ext.declarative import declarative_base
 2 | 
 3 | Base = declarative_base()
 4 | 
 5 | class SomeClass(Base):
 6 |     __tablename__ = 'some_table'
 7 |     id = Column(Integer, primary_key=True)
 8 |     name =  Column(String(50))

在上面,declarative_base()可调用返回一个新的基类,所有映射类都应该继承它。当类定义完成时,将会生成一个新的Tablemapper()

生成的表和映射器可以通过SomeClass类中的__table____mapper__属性访问:

# access the mapped Table
 9 | SomeClass.__table__
10 | 
11 | # access the Mapper
12 | SomeClass.__mapper__

定义属性

在前面的示例中,Column对象会自动使用它们所分配的属性的名称进行命名。

要使用与其映射属性不同的名称明确命名列,只需为该列命名即可。Below, column “some_table_id” is mapped to the “id” attribute of SomeClass, but in SQL will be represented as “some_table_id”:

class SomeClass(Base):
13 |     __tablename__ = 'some_table'
14 |     id = Column("some_table_id", Integer, primary_key=True)

属性可以在其构造后添加到类中,并将它们根据需要添加到基础Tablemapper()定义中:

SomeClass.data = Column('data', Unicode)
15 | SomeClass.related = relationship(RelatedInfo)

使用声明式构造的类可以与使用mapper()显式映射的类自由交互。

尽管不是必需的,但建议所有表共享相同的底层MetaData对象,以便可以毫无问题地解决字符串配置的ForeignKey引用。

访问MetaData

declarative_base()基类包含一个MetaData对象,其中收集了新定义的Table对象。此对象旨在直接访问MetaData特定的操作。例如,为所有表发出CREATE语句:

engine = create_engine('sqlite://')
16 | Base.metadata.create_all(engine)

declarative_base() can also receive a pre-existing MetaData object, which allows a declarative setup to be associated with an already existing traditional collection of Table objects:

mymetadata = MetaData()
17 | Base = declarative_base(metadata=mymetadata)

类构造函数

作为一个方便的功能,declarative_base()在接受关键字参数的类上设置一个默认构造函数,并将它们分配给指定的属性:

e = Engineer(primary_language='python')

映射器配置

声明在内部创建映射到声明表时使用mapper()函数。mapper()的选项直接通过__mapper_args__类属性传递。与往常一样,引用局部映射列的参数可以直接从类声明中引用它们:

from datetime import datetime
18 | 
19 | class Widget(Base):
20 |     __tablename__ = 'widgets'
21 | 
22 |     id = Column(Integer, primary_key=True)
23 |     timestamp = Column(DateTime, nullable=False)
24 | 
25 |     __mapper_args__ = {
26 |                     'version_id_col': timestamp,
27 |                     'version_id_generator': lambda v:datetime.now()
28 |                 }

定义SQL表达式

有关将属性声明性映射到SQL表达式的示例,请参阅SQL Expressions as Mapped Attributes

-------------------------------------------------------------------------------- /intro.html: -------------------------------------------------------------------------------- 1 |

概述¶ T0>

SQLAlchemy的SQL工具包和ORM是一套python数据库操作的综合工具包。它有多个不同领域的功能,可以单独使用或组合使用。其主要组件如下图所示,包含组件层次上的依赖关系。

http://sqlalchemy.readthedocs.io/en/latest/_images/sqla_arch_small.png

如上图所示,SQLAlchemy 最重要的两个部分是 ORMSQL 表达式语言SQL表达式可以独立于ORM使用。使用 ORM 时,SQL 表达式语言仍然是公开 API 的一部分,因为它在对象关系配置和查询中使用。

文档概述

文档分为三个部分: SQLAlchemy ORMSQLAlchemy 核心方言(Dialects).

SQLAlchemy ORM中, 对象关系映射被充分引入和描述。新用户可以从对象关系教程开始。如果你想要了解自动构建高级SQL以及管理Python对象,推荐阅读此教程。

SQLAlchemy Core 中,主要介绍了SQLAlchemy 的 SQL、数据库集成和描述服务, 这部分的核心是 SQL 表达语言。SQL 表达式是独立于 ORM 包的一套自成一体的工具集, 它可以用来创建易于使用的 SQ 表达式,该 SQL 表达式可通过编程创建、修改和执行,返回游标结果集。对比 ORM 使用域为中心的方式,表达语言提供模式为中心的架构。新用户请从 SQL 表达式教程开始。SQLAlchemy 引擎,链接和池服务同样在SQLAlchemy Core中有描述。

Dialects介绍了所有 SQLAlchemy 支持的数据库和 DBAPI 后端。

代码示例

主要关于ORM的工作代码示例包含在SQLAlchemy发行版中.所有包含的示例应用程序的描述在ORM Examples.中。

还有各种各样的示例涉及核心SQLAlchemy构造以及维基上的ORM, 参见Theatrum Chemicum

安装指南

支持的平台

SQLAlchemy已经针对以下平台进行了测试:

在0.9版本中更改: Python 2.6现在是支持的最小Python版本。

目前不支持的平台包括Jython,IronPython。曾经已经支持 Jython,并且可能会在将来的版本中支持,这取决于Jython本身的状态。

支持的安装方法

SQLAlchemy安装是通过基于setuptools的标准Python方法,通过直接引用setup.py或通过使用pip或其他setuptools,兼容的方法。

在版本1.1中更改: setup.py文件现在需要setuptools;不再支持简单的distutils安装。

通过pip安装

pip可用时,可以从Pypi下载并在一个步骤中安装该分发:

pip install SQLAlchemy

该命令将从Python Cheese Shop下载最新的发布的版SQLAlchemy并将其安装到您的系统中。

为了安装最新的prerelease版本,比如1.1.0b1,pip要求使用--pre标志:

pip install --pre SQLAlchemy

如上所述,如果最新版本是预发行版本,则将安装它而不是最新发布的版本。

使用setup.py 进行安装

否则,您可以使用setup.py脚本从分发安装:

python setup.py install

安装C扩展

SQLAlchemy包含C扩展,它提供了额外的速度提升来处理结果集。这些扩展在cPython的2.xx和3.xx系列上均受支持。

setup.py will automatically build the extensions if an appropriate platform is detected. 如果C扩展的构建失败,由于缺少编译器或其他问题,安装过程将输出警告消息,并在完成报告最终状态时重新运行没有C扩展的构建。

要运行构建/安装而不尝试编译C扩展,可以指定DISABLE_SQLALCHEMY_CEXT环境变量。对于这种情况的用例要么是针对特殊的测试环境,要么是通常的“重建”机制无法解决的罕见情况下的兼容性/构建问题:

export DISABLE_SQLALCHEMY_CEXT=1; python setup.py install

在版本1.1中更改:遗留的--without-cextensions标志已从安装程序中删除,因为它依赖于setuptools的不推荐使用的功能。

在Python 3上安装

SQLAlchemy直接在Python 2或Python 3上运行,并且可以在任何环境中安装,无需任何调整或代码转换。

安装数据库API

SQLAlchemy旨在与针对特定数据库构建的DBAPI实现一起运行,并包含对最流行数据库的支持。The individual database sections in Dialects enumerate the available DBAPIs for each database, including external links.

检查安装的SQLAlchemy版本

本文档涵盖了SQLAlchemy版本1.1。如果您正在使用已安装SQLAlchemy的系统,请从您的Python提示符中检查版本,如下所示:

>>> import sqlalchemy
2 | >>> sqlalchemy.__version__ # doctest: +SKIP
3 | 1.1.0

1.0到1.1迁移

Notes on what’s changed from 1.0 to 1.1 is available here at What’s New in SQLAlchemy 1.1?.

-------------------------------------------------------------------------------- /faq/sqlexpressions.html: -------------------------------------------------------------------------------- 1 |

SQL表达式

如何将SQL表达式呈现为字符串,可能内联了绑定参数?

在绝大多数情况下,SQLAlchemy语句或Query的“字符串化”非常简单:

print(str(statement))

这适用于ORM Query以及任何select()或其他语句。此外,要将语句编译为特定的方言或引擎,如果语句本身尚未绑定到某个语句,您可以将它传递给ClauseElement.compile()

print(statement.compile(someengine))

或者没有Engine

from sqlalchemy.dialects import postgresql
 2 | print(statement.compile(dialect=postgresql.dialect()))

当给定ORM Query对象时,为了获得ClauseElement.compile()方法,我们只需要首先访问statement访问器:

statement = query.statement
 3 | print(statement.compile(someengine))

上述表单将在传递给Python DBAPI时呈现SQL语句,其中包括绑定参数不以内联方式呈现。SQLAlchemy通常不绑定绑定参数,因为这是由Python DBAPI适当地处理的,更不用说绕过绑定参数可能是现代Web应用程序中使用最广泛的安全漏洞。SQLAlchemy在某些情况下(例如发出DDL)的能力有限。为了访问这个功能,可以使用传递给compile_kwargsliteral_binds标志:

from sqlalchemy.sql import table, column, select
 4 | 
 5 | t = table('t', column('x'))
 6 | 
 7 | s = select([t]).where(t.c.x == 5)
 8 | 
 9 | print(s.compile(compile_kwargs={"literal_binds": True}))

上面的方法有一点要注意,它只支持基本类型,例如整数和字符串,而且如果直接使用没有预设值的bindparam(),它将不会能够将其串联起来。

要支持对不支持类型的内联文字渲染,请为包含TypeDecorator.process_literal_param()方法的目标类型实现一个TypeDecorator

from sqlalchemy import TypeDecorator, Integer
10 | 
11 | 
12 | class MyFancyType(TypeDecorator):
13 |     impl = Integer
14 | 
15 |     def process_literal_param(self, value, dialect):
16 |         return "my_fancy_formatting(%s)" % value
17 | 
18 | from sqlalchemy import Table, Column, MetaData
19 | 
20 | tab = Table('mytable', MetaData(), Column('x', MyFancyType()))
21 | 
22 | print(
23 |     tab.select().where(tab.c.x > 5).compile(
24 |         compile_kwargs={"literal_binds": True})
25 | )

产出如下产出:

SELECT mytable.x
26 | FROM mytable
27 | WHERE mytable.x > my_fancy_formatting(5)

为什么.col.in_([])产生col != col为什么不1=0

关于这个问题的一点介绍。SQL中的IN运算符给出了要与列进行比较的元素列表,但通常不会接受空列表,即可以这样说:

column IN (1, 2, 3)

这是无效的说:

column IN ()

SQLAlchemy的Operators.in_()运算符在给出一个空列表时产生这个表达式:

column != column

从版本0.6开始,它也会产生一个警告,指出将会呈现效率较低的比较操作。这个表达式是唯一一个既是数据库不可知的,又能产生正确结果的表达式。

例如,“通过比较1 = 0或1!= 1来评估为假”的幼稚方法不能正确处理空值。表达式如下:

NOT column != column

当“列”为空时不会返回一行,但是不考虑列的表达式:

NOT 1=0

将。

更接近该商标的是以下CASE表达式:

CASE WHEN column IS NOT NULL THEN 1=0 ELSE NULL END

我们不使用这个表达式,因为它的冗长,而且在WHERE子句中它也不被Oracle接受 - 取决于你如何说出它,你会得到“ORA-00905:missing keyword”或者“ORA-00920 :无效的关系运算符“。它的效率还不如完全没有子句的情况下渲染SQL(或者根本不发布SQL,如果语句只是简单的搜索)。

因此,最好的方法是在零长度的参数列表中避免使用IN。相反,如果不应返回行,请不要首先发出查询。警告最好使用Python警告过滤器提升为完全错误状态(请参阅http://docs.python.org/library/warnings.html)。

--------------------------------------------------------------------------------