README.dialects.rst
1========================
2Developing new Dialects
3========================
4
5.. note::
6
7 When studying this file, it's probably a good idea to also
8 familiarize with the README.unittests.rst file, which discusses
9 SQLAlchemy's usage and extension of the pytest test runner.
10
11While SQLAlchemy includes many dialects within the core distribution, the
12trend for new dialects should be that they are published as external
13projects. SQLAlchemy has since version 0.5 featured a "plugin" system
14which allows external dialects to be integrated into SQLAlchemy using
15standard setuptools entry points. As of version 0.8, this system has
16been enhanced, so that a dialect can also be "plugged in" at runtime.
17
18On the testing side, SQLAlchemy as of 0.8 also includes a "dialect
19compliance suite" that is usable by third party libraries. There is no
20longer a strong need for a new dialect to run through SQLAlchemy's full
21testing suite, as a large portion of these tests do not have
22dialect-sensitive functionality. The "dialect compliance suite" should
23be viewed as the primary target for new dialects, and as it continues
24to grow and mature it should become a more thorough and efficient system
25of testing new dialects.
26
27
28Dialect Layout
29===============
30
31The file structure of a dialect is typically similar to the following::
32
33 sqlalchemy-<dialect>/
34 setup.py
35 setup.cfg
36 sqlalchemy_<dialect>/
37 __init__.py
38 base.py
39 <dbapi>.py
40 requirements.py
41 test/
42 conftest.py
43 __init__.py
44 test_suite.py
45 test_<dialect_specific_test>.py
46 ...
47
48An example of this structure can be seen in the Access dialect at
49https://github.com/sqlalchemy/sqlalchemy-access .
50
51Key aspects of this file layout include:
52
53* setup.py - should specify setuptools entrypoints, allowing the
54 dialect to be usable from create_engine(), e.g.::
55
56 entry_points={
57 'sqlalchemy.dialects': [
58 'access = sqlalchemy_access.pyodbc:AccessDialect_pyodbc',
59 'access.pyodbc = sqlalchemy_access.pyodbc:AccessDialect_pyodbc',
60 ]
61 }
62
63 Above, the two entrypoints ``access`` and ``access.pyodbc`` allow URLs to be
64 used such as::
65
66 create_engine("access://user:pw@dsn")
67
68 create_engine("access+pyodbc://user:pw@dsn")
69
70* setup.cfg - this file contains the traditional contents such as [egg_info],
71 and [tool:pytest] directives, but also contains new directives that are used
72 by SQLAlchemy's testing framework. E.g. for Access::
73
74 [egg_info]
75 tag_build = dev
76
77 [tool:pytest]
78 addopts= --tb native -v -r fxX --maxfail=25 -p no:warnings
79 python_files=test/*test_*.py
80
81 [sqla_testing]
82 requirement_cls=sqlalchemy_access.requirements:Requirements
83 profile_file=test/profiles.txt
84
85 [db]
86 default=access+pyodbc://admin@access_test
87 sqlite=sqlite:///:memory:
88
89 Above, the ``[sqla_testing]`` section contains configuration used by
90 SQLAlchemy's test plugin. The ``[tool:pytest]`` section
91 include directives to help with these runners. When using pytest
92 the test/conftest.py file will bootstrap SQLAlchemy's plugin.
93
94* test/conftest.py - This script bootstraps SQLAlchemy's pytest plugin
95 into the pytest runner. This
96 script can also be used to install your third party dialect into
97 SQLAlchemy without using the setuptools entrypoint system; this allows
98 your dialect to be present without any explicit setup.py step needed.
99 The other portion invokes SQLAlchemy's pytest plugin::
100
101 from sqlalchemy.dialects import registry
102
103 registry.register("access", "sqlalchemy_access.pyodbc", "AccessDialect_pyodbc")
104 registry.register("access.pyodbc", "sqlalchemy_access.pyodbc", "AccessDialect_pyodbc")
105
106 from sqlalchemy.testing.plugin.pytestplugin import *
107
108 Where above, the ``registry`` module, introduced in SQLAlchemy 0.8, provides
109 an in-Python means of installing the dialect entrypoints without the use
110 of setuptools, using the ``registry.register()`` function in a way that
111 is similar to the ``entry_points`` directive we placed in our ``setup.py``.
112
113* requirements.py - The ``requirements.py`` file is where directives
114 regarding database and dialect capabilities are set up.
115 SQLAlchemy's tests are often annotated with decorators that mark
116 tests as "skip" or "fail" for particular backends. Over time, this
117 system has been refined such that specific database and DBAPI names
118 are mentioned less and less, in favor of @requires directives which
119 state a particular capability. The requirement directive is linked
120 to target dialects using a ``Requirements`` subclass. The custom
121 ``Requirements`` subclass is specified in the ``requirements.py`` file
122 and is made available to SQLAlchemy's test runner using the
123 ``requirement_cls`` directive inside the ``[sqla_testing]`` section.
124
125 For a third-party dialect, the custom ``Requirements`` class can
126 usually specify a simple yes/no answer for a particular system. For
127 example, a requirements file that specifies a database that supports
128 the RETURNING construct but does not support nullable boolean
129 columns might look like this::
130
131 # sqlalchemy_access/requirements.py
132
133 from sqlalchemy.testing.requirements import SuiteRequirements
134
135 from sqlalchemy.testing import exclusions
136
137 class Requirements(SuiteRequirements):
138 @property
139 def table_reflection(self):
140 return exclusions.closed()
141
142 @property
143 def returning(self):
144 return exclusions.open()
145
146 The ``SuiteRequirements`` class in
147 ``sqlalchemy.testing.requirements`` contains a large number of
148 requirements rules, which attempt to have reasonable defaults. The
149 tests will report on those requirements found as they are run.
150
151 The requirements system can also be used when running SQLAlchemy's
152 primary test suite against the external dialect. In this use case,
153 a ``--dburi`` as well as a ``--requirements`` flag are passed to SQLAlchemy's
154 test runner so that exclusions specific to the dialect take place::
155
156 cd /path/to/sqlalchemy
157 pytest -v \
158 --requirements sqlalchemy_access.requirements:Requirements \
159 --dburi access+pyodbc://admin@access_test
160
161* test_suite.py - Finally, the ``test_suite.py`` module represents a
162 stub test suite, which pulls in the actual SQLAlchemy test suite.
163 To pull in the suite as a whole, it can be imported in one step::
164
165 # test/test_suite.py
166
167 from sqlalchemy.testing.suite import *
168
169 That's all that's needed - the ``sqlalchemy.testing.suite`` package
170 contains an ever expanding series of tests, most of which should be
171 annotated with specific requirement decorators so that they can be
172 fully controlled. To specifically modify some of the tests, they can
173 be imported by name and subclassed::
174
175 from sqlalchemy.testing.suite import *
176
177 from sqlalchemy.testing.suite import ComponentReflectionTest as _ComponentReflectionTest
178
179 class ComponentReflectionTest(_ComponentReflectionTest):
180 @classmethod
181 def define_views(cls, metadata, schema):
182 # bypass the "define_views" section of the
183 # fixture
184 return
185
186Going Forward
187==============
188
189The third-party dialect can be distributed like any other Python
190module on PyPI. Links to prominent dialects can be featured within
191SQLAlchemy's own documentation; contact the developers (see AUTHORS)
192for help with this.
193
194While SQLAlchemy includes many dialects built in, it remains to be
195seen if the project as a whole might move towards "plugin" model for
196all dialects, including all those currently built in. Now that
197SQLAlchemy's dialect API is mature and the test suite is not far
198behind, it may be that a better maintenance experience can be
199delivered by having all dialects separately maintained and released.
200
201As new versions of SQLAlchemy are released, the test suite and
202requirements file will receive new tests and changes. The dialect
203maintainer would normally keep track of these changes and make
204adjustments as needed.
205
206
README.rst
1SQLAlchemy
2==========
3
4|PyPI| |Python| |Downloads|
5
6.. |PyPI| image:: https://img.shields.io/pypi/v/sqlalchemy
7 :target: https://pypi.org/project/sqlalchemy
8 :alt: PyPI
9
10.. |Python| image:: https://img.shields.io/pypi/pyversions/sqlalchemy
11 :target: https://pypi.org/project/sqlalchemy
12 :alt: PyPI - Python Version
13
14.. |Downloads| image:: https://img.shields.io/pypi/dm/sqlalchemy
15 :target: https://pypi.org/project/sqlalchemy
16 :alt: PyPI - Downloads
17
18
19The Python SQL Toolkit and Object Relational Mapper
20
21Introduction
22-------------
23
24SQLAlchemy is the Python SQL toolkit and Object Relational Mapper
25that gives application developers the full power and
26flexibility of SQL. SQLAlchemy provides a full suite
27of well known enterprise-level persistence patterns,
28designed for efficient and high-performing database
29access, adapted into a simple and Pythonic domain
30language.
31
32Major SQLAlchemy features include:
33
34* An industrial strength ORM, built
35 from the core on the identity map, unit of work,
36 and data mapper patterns. These patterns
37 allow transparent persistence of objects
38 using a declarative configuration system.
39 Domain models
40 can be constructed and manipulated naturally,
41 and changes are synchronized with the
42 current transaction automatically.
43* A relationally-oriented query system, exposing
44 the full range of SQL's capabilities
45 explicitly, including joins, subqueries,
46 correlation, and most everything else,
47 in terms of the object model.
48 Writing queries with the ORM uses the same
49 techniques of relational composition you use
50 when writing SQL. While you can drop into
51 literal SQL at any time, it's virtually never
52 needed.
53* A comprehensive and flexible system
54 of eager loading for related collections and objects.
55 Collections are cached within a session,
56 and can be loaded on individual access, all
57 at once using joins, or by query per collection
58 across the full result set.
59* A Core SQL construction system and DBAPI
60 interaction layer. The SQLAlchemy Core is
61 separate from the ORM and is a full database
62 abstraction layer in its own right, and includes
63 an extensible Python-based SQL expression
64 language, schema metadata, connection pooling,
65 type coercion, and custom types.
66* All primary and foreign key constraints are
67 assumed to be composite and natural. Surrogate
68 integer primary keys are of course still the
69 norm, but SQLAlchemy never assumes or hardcodes
70 to this model.
71* Database introspection and generation. Database
72 schemas can be "reflected" in one step into
73 Python structures representing database metadata;
74 those same structures can then generate
75 CREATE statements right back out - all within
76 the Core, independent of the ORM.
77
78SQLAlchemy's philosophy:
79
80* SQL databases behave less and less like object
81 collections the more size and performance start to
82 matter; object collections behave less and less like
83 tables and rows the more abstraction starts to matter.
84 SQLAlchemy aims to accommodate both of these
85 principles.
86* An ORM doesn't need to hide the "R". A relational
87 database provides rich, set-based functionality
88 that should be fully exposed. SQLAlchemy's
89 ORM provides an open-ended set of patterns
90 that allow a developer to construct a custom
91 mediation layer between a domain model and
92 a relational schema, turning the so-called
93 "object relational impedance" issue into
94 a distant memory.
95* The developer, in all cases, makes all decisions
96 regarding the design, structure, and naming conventions
97 of both the object model as well as the relational
98 schema. SQLAlchemy only provides the means
99 to automate the execution of these decisions.
100* With SQLAlchemy, there's no such thing as
101 "the ORM generated a bad query" - you
102 retain full control over the structure of
103 queries, including how joins are organized,
104 how subqueries and correlation is used, what
105 columns are requested. Everything SQLAlchemy
106 does is ultimately the result of a developer-
107 initiated decision.
108* Don't use an ORM if the problem doesn't need one.
109 SQLAlchemy consists of a Core and separate ORM
110 component. The Core offers a full SQL expression
111 language that allows Pythonic construction
112 of SQL constructs that render directly to SQL
113 strings for a target database, returning
114 result sets that are essentially enhanced DBAPI
115 cursors.
116* Transactions should be the norm. With SQLAlchemy's
117 ORM, nothing goes to permanent storage until
118 commit() is called. SQLAlchemy encourages applications
119 to create a consistent means of delineating
120 the start and end of a series of operations.
121* Never render a literal value in a SQL statement.
122 Bound parameters are used to the greatest degree
123 possible, allowing query optimizers to cache
124 query plans effectively and making SQL injection
125 attacks a non-issue.
126
127Documentation
128-------------
129
130Latest documentation is at:
131
132http://www.sqlalchemy.org/docs/
133
134Installation / Requirements
135---------------------------
136
137Full documentation for installation is at
138`Installation <http://www.sqlalchemy.org/docs/intro.html#installation>`_.
139
140Getting Help / Development / Bug reporting
141------------------------------------------
142
143Please refer to the `SQLAlchemy Community Guide <http://www.sqlalchemy.org/support.html>`_.
144
145Code of Conduct
146---------------
147
148Above all, SQLAlchemy places great emphasis on polite, thoughtful, and
149constructive communication between users and developers.
150Please see our current Code of Conduct at
151`Code of Conduct <http://www.sqlalchemy.org/codeofconduct.html>`_.
152
153License
154-------
155
156SQLAlchemy is distributed under the `MIT license
157<http://www.opensource.org/licenses/mit-license.php>`_.
158
159
README.unittests.rst
1=====================
2SQLALCHEMY UNIT TESTS
3=====================
4
5Updated for 1.1, 1.2
6
7Basic Test Running
8==================
9
10A test target exists within the setup.py script. For basic test runs::
11
12 python setup.py test
13
14
15Running with Tox
16================
17
18For more elaborate CI-style test running, the tox script provided will
19run against various Python / database targets. For a basic run against
20Python 2.7 using an in-memory SQLite database::
21
22 tox -e py27-sqlite
23
24The tox runner contains a series of target combinations that can run
25against various combinations of databases. The test suite can be
26run against SQLite with "backend" tests also running against a PostgreSQL
27database::
28
29 tox -e py36-sqlite-postgresql
30
31Or to run just "backend" tests against a MySQL database::
32
33 tox -e py36-mysql-backendonly
34
35Running against backends other than SQLite requires that a database of that
36vendor be available at a specific URL. See "Setting Up Databases" below
37for details.
38
39The pytest Engine
40==================
41
42The tox runner is using pytest to invoke the test suite. Within the realm of
43pytest, SQLAlchemy itself is adding a large series of option and
44customizations to the pytest runner using plugin points, to allow for
45SQLAlchemy's multiple database support, database setup/teardown and
46connectivity, multi process support, as well as lots of skip / database
47selection rules.
48
49Running tests with pytest directly grants more immediate control over
50database options and test selection.
51
52A generic pytest run looks like::
53
54 pytest -n4
55
56Above, the full test suite will run against SQLite, using four processes.
57If the "-n" flag is not used, the pytest-xdist is skipped and the tests will
58run linearly, which will take a pretty long time.
59
60The pytest command line is more handy for running subsets of tests and to
61quickly allow for custom database connections. Example::
62
63 pytest --dburi=postgresql+psycopg2://scott:tiger@localhost/test test/sql/test_query.py
64
65Above will run the tests in the test/sql/test_query.py file (a pretty good
66file for basic "does this database work at all?" to start with) against a
67running PostgreSQL database at the given URL.
68
69The pytest frontend can also run tests against multiple kinds of databases at
70once - a large subset of tests are marked as "backend" tests, which will be run
71against each available backend, and additionally lots of tests are targeted at
72specific backends only, which only run if a matching backend is made available.
73For example, to run the test suite against both PostgreSQL and MySQL at the
74same time::
75
76 pytest -n4 --db postgresql --db mysql
77
78
79Setting Up Databases
80====================
81
82The test suite identifies several built-in database tags that run against
83a pre-set URL. These can be seen using --dbs::
84
85 $ pytest --dbs
86 Available --db options (use --dburi to override)
87 default sqlite:///:memory:
88 firebird firebird://sysdba:masterkey@localhost//Users/classic/foo.fdb
89 mssql mssql+pyodbc://scott:tiger@ms_2008
90 mssql_pymssql mssql+pymssql://scott:tiger@ms_2008
91 mysql mysql://scott:tiger@127.0.0.1:3306/test?charset=utf8
92 oracle oracle://scott:tiger@127.0.0.1:1521
93 oracle8 oracle://scott:tiger@127.0.0.1:1521/?use_ansi=0
94 pg8000 postgresql+pg8000://scott:tiger@127.0.0.1:5432/test
95 postgresql postgresql://scott:tiger@127.0.0.1:5432/test
96 postgresql_psycopg2cffi postgresql+psycopg2cffi://scott:tiger@127.0.0.1:5432/test
97 pymysql mysql+pymysql://scott:tiger@127.0.0.1:3306/test?charset=utf8
98 sqlite sqlite:///:memory:
99 sqlite_file sqlite:///querytest.db
100
101What those mean is that if you have a database running that can be accessed
102by the above URL, you can run the test suite against it using ``--db <name>``.
103
104The URLs are present in the ``setup.cfg`` file. You can make your own URLs by
105creating a new file called ``test.cfg`` and adding your own ``[db]`` section::
106
107 # test.cfg file
108 [db]
109 my_postgresql=postgresql://username:pass@hostname/dbname
110
111Above, we can now run the tests with ``my_postgresql``::
112
113 pytest --db my_postgresql
114
115We can also override the existing names in our ``test.cfg`` file, so that we can run
116with the tox runner also::
117
118 # test.cfg file
119 [db]
120 postgresql=postgresql://username:pass@hostname/dbname
121
122Now when we run ``tox -e py27-postgresql``, it will use our custom URL instead
123of the fixed one in setup.cfg.
124
125Database Configuration
126======================
127
128The test runner will by default create and drop tables within the default
129database that's in the database URL, *unless* the multiprocessing option is in
130use via the pytest "-n" flag, which invokes pytest-xdist. The
131multiprocessing option is **enabled by default** when using the tox runner.
132When multiprocessing is used, the SQLAlchemy testing framework will create a
133new database for each process, and then tear it down after the test run is
134complete. So it will be necessary for the database user to have access to
135CREATE DATABASE in order for this to work. Additionally, as mentioned
136earlier, the database URL must be formatted such that it can be rewritten on
137the fly to refer to these other databases, which means for pyodbc it must refer
138to a hostname/database name combination, not a DSN name.
139
140Several tests require alternate usernames or schemas to be present, which
141are used to test dotted-name access scenarios. On some databases such
142as Oracle or Sybase, these are usernames, and others such as PostgreSQL
143and MySQL they are schemas. The requirement applies to all backends
144except SQLite and Firebird. The names are::
145
146 test_schema
147 test_schema_2 (only used on PostgreSQL and mssql)
148
149Please refer to your vendor documentation for the proper syntax to create
150these namespaces - the database user must have permission to create and drop
151tables within these schemas. Its perfectly fine to run the test suite
152without these namespaces present, it only means that a handful of tests which
153expect them to be present will fail.
154
155Additional steps specific to individual databases are as follows::
156
157 POSTGRESQL: To enable unicode testing with JSONB, create the
158 database with UTF8 encoding::
159
160 postgres=# create database test with owner=scott encoding='utf8' template=template0;
161
162 To include tests for HSTORE, create the HSTORE type engine::
163
164 postgres=# \c test;
165 You are now connected to database "test" as user "postgresql".
166 test=# create extension hstore;
167 CREATE EXTENSION
168
169 Full-text search configuration should be set to English, else
170 several tests of ``.match()`` will fail. This can be set (if it isn't so
171 already) with:
172
173 ALTER DATABASE test SET default_text_search_config = 'pg_catalog.english'
174
175 For two-phase transaction support, the max_prepared_transactions
176 configuration variable must be set to a non-zero value in postgresql.conf.
177 See
178 https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-MAX-PREPARED-TRANSACTIONS
179 for further background.
180
181 ORACLE: a user named "test_schema" is created in addition to the default
182 user.
183
184 The primary database user needs to be able to create and drop tables,
185 synonyms, and constraints within the "test_schema" user. For this
186 to work fully, including that the user has the "REFERENCES" role
187 in a remote schema for tables not yet defined (REFERENCES is per-table),
188 it is required that the test the user be present in the "DBA" role:
189
190 grant dba to scott;
191
192 MSSQL: Tests that involve multiple connections require Snapshot Isolation
193 ability implemented on the test database in order to prevent deadlocks that
194 will occur with record locking isolation. This feature is only available
195 with MSSQL 2005 and greater. You must enable snapshot isolation at the
196 database level and set the default cursor isolation with two SQL commands:
197
198 ALTER DATABASE MyDatabase SET ALLOW_SNAPSHOT_ISOLATION ON
199
200 ALTER DATABASE MyDatabase SET READ_COMMITTED_SNAPSHOT ON
201
202
203CONFIGURING LOGGING
204-------------------
205SQLAlchemy logs its activity and debugging through Python's logging package.
206Any log target can be directed to the console with command line options, such
207as::
208
209 $ ./pytest test/orm/test_unitofwork.py -s \
210 --log-debug=sqlalchemy.pool --log-info=sqlalchemy.engine
211
212Above we add the pytest "-s" flag so that standard out is not suppressed.
213
214
215DEVELOPING AND TESTING NEW DIALECTS
216-----------------------------------
217
218See the file README.dialects.rst for detail on dialects.
219
220
221