From: Jason Kirtland Date: Fri, 15 Jun 2007 22:35:53 +0000 (+0000) Subject: - Added testbase.Table and testbase.Column, interceptors that can set up X-Git-Tag: rel_0_4_6~196 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5b779d30c31f6d07180a6b2e5f95914aed7a7071;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Added testbase.Table and testbase.Column, interceptors that can set up test-run- and dialect-specific options on those objects All tests re-pointed to go through the interceptors - Removed mysql_engine= from table declarations, replaced with a general flag indicating storage requirements - Added ability to choose a global MySQL storage engine for all tests --mysql-engine= If none is specified, tests use the old db-default/InnoDB behavior - Added ability to append arbitrary table creation params --table-option=KEY=VALUE For MySQL 3, use this to set mysql_type instead of --mysql-engine - Removed a couple dead test modules --- diff --git a/test/dialect/mysql.py b/test/dialect/mysql.py index bcef161a34..784993cc45 100644 --- a/test/dialect/mysql.py +++ b/test/dialect/mysql.py @@ -2,6 +2,7 @@ from testbase import PersistTest, AssertMixin import testbase from sqlalchemy import * from sqlalchemy.databases import mysql +from testbase import Table, Column import sys, StringIO db = testbase.db diff --git a/test/engine/autoconnect_engine.py b/test/engine/autoconnect_engine.py deleted file mode 100644 index 69c2c33f54..0000000000 --- a/test/engine/autoconnect_engine.py +++ /dev/null @@ -1,90 +0,0 @@ -from testbase import PersistTest -import testbase -from sqlalchemy import * -from sqlalchemy.ext.proxy import AutoConnectEngine - -import os - -# -# Define an engine, table and mapper at the module level, to show that the -# table and mapper can be used with different real engines in multiple threads -# - - -module_engine = AutoConnectEngine( testbase.db_uri ) -users = Table('users', module_engine, - Column('user_id', Integer, primary_key=True), - Column('user_name', String(16)), - Column('password', String(20)) - ) - -class User(object): - pass - - -class AutoConnectEngineTest1(PersistTest): - - def setUp(self): - clear_mappers() - objectstore.clear() - - def test_engine_connect(self): - users.create() - assign_mapper(User, users) - try: - trans = objectstore.begin() - - user = User() - user.user_name='fred' - user.password='*' - trans.commit() - - # select - sqluser = User.select_by(user_name='fred')[0] - assert sqluser.user_name == 'fred' - - # modify - sqluser.user_name = 'fred jones' - - # commit - saves everything that changed - objectstore.commit() - - allusers = [ user.user_name for user in User.select() ] - assert allusers == [ 'fred jones' ] - finally: - users.drop() - - - - -if __name__ == "__main__": - testbase.main() - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/engine/execute.py b/test/engine/execute.py index 33c2520182..c8e23d3deb 100644 --- a/test/engine/execute.py +++ b/test/engine/execute.py @@ -4,7 +4,7 @@ import unittest, sys, datetime import tables db = testbase.db from sqlalchemy import * - +from testbase import Table, Column class ExecuteTest(testbase.PersistTest): def setUpAll(self): @@ -13,7 +13,6 @@ class ExecuteTest(testbase.PersistTest): users = Table('users', metadata, Column('user_id', INT, primary_key = True), Column('user_name', VARCHAR(20)), - mysql_engine='InnoDB' ) metadata.create_all() diff --git a/test/engine/metadata.py b/test/engine/metadata.py index 1165170e8b..c3c6441ef1 100644 --- a/test/engine/metadata.py +++ b/test/engine/metadata.py @@ -1,5 +1,6 @@ import testbase from sqlalchemy import * +from testbase import Table, Column class MetaDataTest(testbase.PersistTest): def test_metadata_connect(self): @@ -14,4 +15,4 @@ class MetaDataTest(testbase.PersistTest): metadata.drop_all() if __name__ == '__main__': - testbase.main() \ No newline at end of file + testbase.main() diff --git a/test/engine/reflection.py b/test/engine/reflection.py index 41cd236748..d845e43c1f 100644 --- a/test/engine/reflection.py +++ b/test/engine/reflection.py @@ -6,7 +6,7 @@ import sqlalchemy.ansisql as ansisql from sqlalchemy import * from sqlalchemy.exceptions import NoSuchTableError import sqlalchemy.databases.mysql as mysql - +from testbase import Table, Column import unittest, re, StringIO class ReflectionTest(PersistTest): @@ -15,6 +15,10 @@ class ReflectionTest(PersistTest): use_string_defaults = use_function_defaults or testbase.db.engine.__module__.endswith('sqlite') + if (testbase.db.engine.name == 'mysql' and + testbase.db.dialect.get_version_info(testbase.db) < (4, 1, 1)): + return + if use_function_defaults: defval = func.current_date() deftype = Date @@ -54,14 +58,14 @@ class ReflectionTest(PersistTest): Column('test_passivedefault4', deftype3, PassiveDefault(defval3)), Column('test9', Binary(100)), Column('test_numeric', Numeric(None, None)), - mysql_engine='InnoDB' + test_needs_fk=True, ) - + addresses = Table('engine_email_addresses', meta, Column('address_id', Integer, primary_key = True), Column('remote_user_id', Integer, ForeignKey(users.c.user_id)), Column('email_address', String(20)), - mysql_engine='InnoDB' + test_needs_fk=True, ) meta.drop_all() @@ -320,6 +324,10 @@ class ReflectionTest(PersistTest): def test_composite_fk(self): """test reflection of composite foreign keys""" + + if (testbase.db.engine.name == 'mysql' and + testbase.db.dialect.get_version_info(testbase.db) < (4, 1, 1)): + return meta = BoundMetaData(testbase.db) table = Table( 'multi', meta, @@ -328,7 +336,7 @@ class ReflectionTest(PersistTest): Column('multi_hoho', Integer, primary_key=True), Column('name', String(50), nullable=False), Column('val', String(100)), - mysql_engine='InnoDB' + test_needs_fk=True, ) table2 = Table('multi2', meta, Column('id', Integer, primary_key=True), @@ -337,7 +345,7 @@ class ReflectionTest(PersistTest): Column('lala', Integer), Column('data', String(50)), ForeignKeyConstraint(['foo', 'bar', 'lala'], ['multi.multi_id', 'multi.multi_rev', 'multi.multi_hoho']), - mysql_engine='InnoDB' + test_needs_fk=True, ) assert table.c.multi_hoho meta.create_all() diff --git a/test/engine/transaction.py b/test/engine/transaction.py index 86093218ba..96fe7acf4d 100644 --- a/test/engine/transaction.py +++ b/test/engine/transaction.py @@ -5,7 +5,7 @@ import tables db = testbase.db from sqlalchemy import * from sqlalchemy.orm import * - +from testbase import Table, Column class TransactionTest(testbase.PersistTest): def setUpAll(self): @@ -14,7 +14,7 @@ class TransactionTest(testbase.PersistTest): users = Table('query_users', metadata, Column('user_id', INT, primary_key = True), Column('user_name', VARCHAR(20)), - mysql_engine='InnoDB' + test_needs_acid=True, ) users.create(testbase.db) @@ -132,6 +132,7 @@ class AutoRollbackTest(testbase.PersistTest): users = Table('deadlock_users', metadata, Column('user_id', INT, primary_key = True), Column('user_name', VARCHAR(20)), + test_needs_acid=True, ) users.create(conn1) conn1.execute("select * from deadlock_users") @@ -150,7 +151,7 @@ class TLTransactionTest(testbase.PersistTest): users = Table('query_users', metadata, Column('user_id', INT, primary_key = True), Column('user_name', VARCHAR(20)), - mysql_engine='InnoDB' + test_needs_acid=True, ) users.create(tlengine) def tearDown(self): @@ -356,7 +357,7 @@ class ForUpdateTest(testbase.PersistTest): counters = Table('forupdate_counters', metadata, Column('counter_id', INT, primary_key = True), Column('counter_value', INT), - mysql_engine='InnoDB' + test_needs_acid=True, ) counters.create(testbase.db) def tearDown(self): diff --git a/test/ext/assignmapper.py b/test/ext/assignmapper.py index 479e9f399e..c5a2d31916 100644 --- a/test/ext/assignmapper.py +++ b/test/ext/assignmapper.py @@ -6,6 +6,7 @@ from sqlalchemy.orm import create_session, clear_mappers, relation, class_mapper from sqlalchemy.ext.assignmapper import assign_mapper from sqlalchemy.ext.sessioncontext import SessionContext +from testbase import Table, Column class OverrideAttributesTest(PersistTest): def setUpAll(self): @@ -46,4 +47,4 @@ class OverrideAttributesTest(PersistTest): assert SomeObject.get_by(id=s.id).options[0].id == sso.id if __name__ == '__main__': - testbase.main() \ No newline at end of file + testbase.main() diff --git a/test/ext/associationproxy.py b/test/ext/associationproxy.py index 7a5731d514..98229f397a 100644 --- a/test/ext/associationproxy.py +++ b/test/ext/associationproxy.py @@ -5,6 +5,7 @@ import testbase from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy.ext.associationproxy import * +from testbase import Table, Column db = testbase.db diff --git a/test/ext/orderinglist.py b/test/ext/orderinglist.py index c2811d5ce0..dc75d066d7 100644 --- a/test/ext/orderinglist.py +++ b/test/ext/orderinglist.py @@ -5,6 +5,7 @@ import testbase from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy.ext.orderinglist import * +from testbase import Table, Column db = testbase.db metadata = None diff --git a/test/ext/selectresults.py b/test/ext/selectresults.py index eeaff7d549..8f77b323a6 100644 --- a/test/ext/selectresults.py +++ b/test/ext/selectresults.py @@ -4,6 +4,7 @@ import tables from sqlalchemy import * from sqlalchemy.orm import * +from testbase import Table, Column from sqlalchemy.ext.selectresults import SelectResultsExt, SelectResults diff --git a/test/ext/wsgi_test.py b/test/ext/wsgi_test.py deleted file mode 100644 index 1330f88b63..0000000000 --- a/test/ext/wsgi_test.py +++ /dev/null @@ -1,122 +0,0 @@ -"""Interactive wsgi test - -Small WSGI application that uses a table and mapper defined at the module -level, with per-application uris enabled by the ProxyEngine. - -Requires the wsgiutils package from: - -http://www.owlfish.com/software/wsgiutils/ - -Run the script with python wsgi_test.py, then visit http://localhost:8080/a -and http://localhost:8080/b with a browser. You should see two distinct lists -of colors. -""" - -from sqlalchemy import * -from sqlalchemy.ext.proxy import ProxyEngine -from wsgiutils import wsgiServer - -engine = ProxyEngine() - -colors = Table('colors', engine, - Column('id', Integer, primary_key=True), - Column('name', String(32)), - Column('hex', String(6))) - -class Color(object): - pass - -assign_mapper(Color, colors) - -data = { 'a': (('fff','white'), ('aaa','gray'), ('000','black'), - ('f00', 'red'), ('0f0', 'green')), - 'b': (('00f','blue'), ('ff0', 'yellow'), ('0ff','purple')) } - -db_uri = { 'a': 'sqlite://filename=wsgi_db_a.db', - 'b': 'sqlite://filename=wsgi_db_b.db' } - -def app(dataset): - print '... connecting to database %s: %s' % (dataset, db_uri[dataset]) - engine.connect(db_uri[dataset], echo=True, echo_pool=True) - colors.create() - - print '... populating data into %s' % db_uri[dataset] - for hex, name in data[dataset]: - c = Color() - c.hex = hex - c.name = name - objectstore.commit() - objectstore.clear() - - def call(environ, start_response): - engine.connect(db_uri[dataset], echo=True, echo_pool=True) - - # NOTE: must clear objectstore on each request, or you'll see - # objects from another thread here - objectstore.clear() - objectstore.begin() - - c = Color.select() - - start_response('200 OK', [('content-type','text/html')]) - yield 'Test dataset %s' % dataset - yield '' - yield '

uri: %s

' % db_uri[dataset] - yield '

engine:

%s

' % engine.engine - yield '

Colors!

' - for color in c: - yield '
%s
' % (color.hex, - color.name) - yield '' - return call - -def cleanup(): - for uri in db_uri.values(): - print "Cleaning db %s" % uri - engine.connect(uri) - colors.drop() - -def run_server(apps, host='localhost', port=8080): - print "Serving test app at http://%s:%s/" % (host, port) - print "Visit http://%(host)s:%(port)s/a and " \ - "http://%(host)s:%(port)s/b to test apps" % {'host': host, - 'port': port} - - server = wsgiServer.WSGIServer((host, port), apps, serveFiles=False) - try: - server.serve_forever() - except: - cleanup() - raise - -if __name__ == '__main__': - run_server({'/a':app('a'), '/b':app('b')}) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/orm/association.py b/test/orm/association.py index c751ac8a17..61e9bce5f4 100644 --- a/test/orm/association.py +++ b/test/orm/association.py @@ -2,7 +2,7 @@ import testbase from sqlalchemy import * from sqlalchemy.orm import * - +from testbase import Table, Column class AssociationTest(testbase.PersistTest): def setUpAll(self): diff --git a/test/orm/cascade.py b/test/orm/cascade.py index 80b846c682..27e8e7c8fe 100644 --- a/test/orm/cascade.py +++ b/test/orm/cascade.py @@ -4,6 +4,7 @@ import unittest, sys, datetime from sqlalchemy.ext.sessioncontext import SessionContext from sqlalchemy import * from sqlalchemy.orm import * +from testbase import Table, Column class O2MCascadeTest(testbase.AssertMixin): def tearDown(self): diff --git a/test/orm/compile.py b/test/orm/compile.py index 604c75d488..85aa7c927e 100644 --- a/test/orm/compile.py +++ b/test/orm/compile.py @@ -1,6 +1,7 @@ import testbase from sqlalchemy import * from sqlalchemy.orm import * +from testbase import Table, Column class CompileTest(testbase.AssertMixin): diff --git a/test/orm/cycles.py b/test/orm/cycles.py index dc086b635b..e9e5f4b902 100644 --- a/test/orm/cycles.py +++ b/test/orm/cycles.py @@ -4,6 +4,7 @@ from sqlalchemy import * from sqlalchemy.orm import * import StringIO import testbase +from testbase import Table, Column from tables import * import tables diff --git a/test/orm/eagertest1.py b/test/orm/eagertest1.py index da94c782ab..dd3ad92e57 100644 --- a/test/orm/eagertest1.py +++ b/test/orm/eagertest1.py @@ -3,6 +3,7 @@ import testbase import unittest, sys, os from sqlalchemy import * from sqlalchemy.orm import * +from testbase import Table, Column import datetime class EagerTest(AssertMixin): diff --git a/test/orm/eagertest2.py b/test/orm/eagertest2.py index e7bc4c2cb0..0b51ab9dbf 100644 --- a/test/orm/eagertest2.py +++ b/test/orm/eagertest2.py @@ -3,8 +3,9 @@ import testbase import unittest, sys, os from sqlalchemy import * from sqlalchemy.orm import * -import datetime from sqlalchemy.ext.sessioncontext import SessionContext +from testbase import Table, Column +import datetime class EagerTest(AssertMixin): def setUpAll(self): diff --git a/test/orm/eagertest3.py b/test/orm/eagertest3.py index 6453d7ddf7..bfcd166434 100644 --- a/test/orm/eagertest3.py +++ b/test/orm/eagertest3.py @@ -3,6 +3,7 @@ import testbase from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy.ext.selectresults import SelectResults +from testbase import Table, Column import random class EagerTest(AssertMixin): diff --git a/test/orm/entity.py b/test/orm/entity.py index 4fc15fef16..a5346597b4 100644 --- a/test/orm/entity.py +++ b/test/orm/entity.py @@ -1,9 +1,10 @@ from testbase import PersistTest, AssertMixin import unittest +import testbase from sqlalchemy import * from sqlalchemy.orm import * -import testbase from sqlalchemy.ext.sessioncontext import SessionContext +from testbase import Table, Column from tables import * import tables diff --git a/test/orm/fixtures.py b/test/orm/fixtures.py index b79fdb5ba5..57991735e5 100644 --- a/test/orm/fixtures.py +++ b/test/orm/fixtures.py @@ -1,4 +1,5 @@ from sqlalchemy import * +from testbase import Table, Column class Base(object): def __init__(self, **kwargs): diff --git a/test/orm/generative.py b/test/orm/generative.py index d463928165..ad07b5b21a 100644 --- a/test/orm/generative.py +++ b/test/orm/generative.py @@ -5,6 +5,7 @@ import tables from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy import exceptions +from testbase import Table, Column class Foo(object): pass diff --git a/test/orm/inheritance/abc_inheritance.py b/test/orm/inheritance/abc_inheritance.py index d85ac39c71..7677311739 100644 --- a/test/orm/inheritance/abc_inheritance.py +++ b/test/orm/inheritance/abc_inheritance.py @@ -1,5 +1,6 @@ from sqlalchemy import * from sqlalchemy.orm import * +from testbase import Table, Column from sqlalchemy.orm.sync import ONETOMANY, MANYTOONE import testbase diff --git a/test/orm/inheritance/basic.py b/test/orm/inheritance/basic.py index d8ae774081..1437cde1fb 100644 --- a/test/orm/inheritance/basic.py +++ b/test/orm/inheritance/basic.py @@ -1,6 +1,7 @@ import testbase from sqlalchemy import * from sqlalchemy.orm import * +from testbase import Table, Column class O2MTest(testbase.ORMTest): diff --git a/test/orm/inheritance/concrete.py b/test/orm/inheritance/concrete.py index af5b7da0ea..d0d03210bf 100644 --- a/test/orm/inheritance/concrete.py +++ b/test/orm/inheritance/concrete.py @@ -1,6 +1,7 @@ from sqlalchemy import * from sqlalchemy.orm import * import testbase +from testbase import Table, Column class ConcreteTest1(testbase.ORMTest): def define_tables(self, metadata): @@ -64,4 +65,4 @@ class ConcreteTest1(testbase.ORMTest): if __name__ == '__main__': - testbase.main() \ No newline at end of file + testbase.main() diff --git a/test/orm/inheritance/magazine.py b/test/orm/inheritance/magazine.py index 880ede5918..60d690388c 100644 --- a/test/orm/inheritance/magazine.py +++ b/test/orm/inheritance/magazine.py @@ -1,6 +1,7 @@ import testbase from sqlalchemy import * from sqlalchemy.orm import * +from testbase import Table, Column class BaseObject(object): diff --git a/test/orm/inheritance/manytomany.py b/test/orm/inheritance/manytomany.py index 9571ccf2fc..97885c1b08 100644 --- a/test/orm/inheritance/manytomany.py +++ b/test/orm/inheritance/manytomany.py @@ -1,6 +1,7 @@ import testbase from sqlalchemy import * from sqlalchemy.orm import * +from testbase import Table, Column class InheritTest(testbase.ORMTest): diff --git a/test/orm/inheritance/poly_linked_list.py b/test/orm/inheritance/poly_linked_list.py index 406981e7a4..a9482f28c9 100644 --- a/test/orm/inheritance/poly_linked_list.py +++ b/test/orm/inheritance/poly_linked_list.py @@ -1,6 +1,8 @@ import testbase from sqlalchemy import * from sqlalchemy.orm import * +from testbase import Table, Column + class PolymorphicCircularTest(testbase.ORMTest): keep_mappers = True diff --git a/test/orm/inheritance/polymorph.py b/test/orm/inheritance/polymorph.py index b166cc19d6..0fadfa1950 100644 --- a/test/orm/inheritance/polymorph.py +++ b/test/orm/inheritance/polymorph.py @@ -1,10 +1,11 @@ +"""tests basic polymorphic mapper loading/saving, minimal relations""" + import testbase from sqlalchemy import * from sqlalchemy.orm import * - +from testbase import Table, Column import sets -# tests basic polymorphic mapper loading/saving, minimal relations class Person(object): def __init__(self, **kwargs): diff --git a/test/orm/inheritance/polymorph2.py b/test/orm/inheritance/polymorph2.py index a678994493..664fb78a38 100644 --- a/test/orm/inheritance/polymorph2.py +++ b/test/orm/inheritance/polymorph2.py @@ -1,8 +1,9 @@ from sqlalchemy import * from sqlalchemy.orm import * - +from testbase import Table, Column import testbase + class AttrSettable(object): def __init__(self, **kwargs): [setattr(self, k, v) for k, v in kwargs.iteritems()] diff --git a/test/orm/inheritance/productspec.py b/test/orm/inheritance/productspec.py index 510f9ec8b6..aff89f5b77 100644 --- a/test/orm/inheritance/productspec.py +++ b/test/orm/inheritance/productspec.py @@ -1,6 +1,7 @@ import testbase from sqlalchemy import * from sqlalchemy.orm import * +from testbase import Table, Column from datetime import datetime diff --git a/test/orm/inheritance/single.py b/test/orm/inheritance/single.py index 87ee0e57c0..1839f3b036 100644 --- a/test/orm/inheritance/single.py +++ b/test/orm/inheritance/single.py @@ -1,8 +1,9 @@ from sqlalchemy import * from sqlalchemy.orm import * - +from testbase import Table, Column import testbase + class SingleInheritanceTest(testbase.AssertMixin): def setUpAll(self): metadata = BoundMetaData(testbase.db) @@ -62,4 +63,4 @@ class SingleInheritanceTest(testbase.AssertMixin): assert session.query(JuniorEngineer).select() == [e2] if __name__ == '__main__': - testbase.main() \ No newline at end of file + testbase.main() diff --git a/test/orm/lazytest1.py b/test/orm/lazytest1.py index 0a88785cda..d6c094ddd3 100644 --- a/test/orm/lazytest1.py +++ b/test/orm/lazytest1.py @@ -3,6 +3,7 @@ import testbase import unittest, sys, os from sqlalchemy import * from sqlalchemy.orm import * +from testbase import Table, Column import datetime class LazyTest(AssertMixin): diff --git a/test/orm/manytomany.py b/test/orm/manytomany.py index 01df54d816..6a9bd2126c 100644 --- a/test/orm/manytomany.py +++ b/test/orm/manytomany.py @@ -1,6 +1,7 @@ import testbase from sqlalchemy import * from sqlalchemy.orm import * +from testbase import Table, Column import string class Place(object): diff --git a/test/orm/memusage.py b/test/orm/memusage.py index e53890d69f..04cc6d220b 100644 --- a/test/orm/memusage.py +++ b/test/orm/memusage.py @@ -4,6 +4,7 @@ from sqlalchemy.orm import mapperlib, session, unitofwork, attributes Mapper = mapperlib.Mapper import gc import testbase +from testbase import Table, Column import tables class A(object):pass diff --git a/test/orm/merge.py b/test/orm/merge.py index 41a755afb4..66e21ed8d1 100644 --- a/test/orm/merge.py +++ b/test/orm/merge.py @@ -2,6 +2,7 @@ from testbase import PersistTest, AssertMixin import testbase from sqlalchemy import * from sqlalchemy.orm import * +from testbase import Table, Column from tables import * import tables @@ -166,4 +167,4 @@ class MergeTest(AssertMixin): if __name__ == "__main__": testbase.main() - \ No newline at end of file + diff --git a/test/orm/onetoone.py b/test/orm/onetoone.py index e78eddb093..0f8ddd4188 100644 --- a/test/orm/onetoone.py +++ b/test/orm/onetoone.py @@ -2,6 +2,7 @@ import testbase from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy.ext.sessioncontext import SessionContext +from testbase import Table, Column class Jack(object): def __repr__(self): diff --git a/test/orm/query.py b/test/orm/query.py index 9527b25d83..6b77224e85 100644 --- a/test/orm/query.py +++ b/test/orm/query.py @@ -1,6 +1,7 @@ from sqlalchemy import * from sqlalchemy.orm import * import testbase +from testbase import Table, Column from fixtures import * class Base(object): diff --git a/test/orm/relationships.py b/test/orm/relationships.py index e5fd0dd328..e1197e8f74 100644 --- a/test/orm/relationships.py +++ b/test/orm/relationships.py @@ -1,12 +1,10 @@ import testbase import unittest, sys, datetime - -db = testbase.db -#db. - from sqlalchemy import * from sqlalchemy.orm import * +from testbase import Table, Column +db = testbase.db class RelationTest(testbase.PersistTest): """this is essentially an extension of the "dependency.py" topological sort test. diff --git a/test/orm/sessioncontext.py b/test/orm/sessioncontext.py index 57615ed583..f6cd8f9f48 100644 --- a/test/orm/sessioncontext.py +++ b/test/orm/sessioncontext.py @@ -6,12 +6,12 @@ from sqlalchemy import * from sqlalchemy.orm import * import testbase +from testbase import Table, Column metadata = MetaData() users = Table('users', metadata, Column('user_id', Integer, Sequence('user_id_seq', optional=True), primary_key = True), Column('user_name', String(40)), - mysql_engine='innodb' ) class SessionContextTest(AssertMixin): diff --git a/test/orm/unitofwork.py b/test/orm/unitofwork.py index 1dcd40236a..eed8cc2fbc 100644 --- a/test/orm/unitofwork.py +++ b/test/orm/unitofwork.py @@ -2,6 +2,7 @@ from testbase import PersistTest, AssertMixin from sqlalchemy import * from sqlalchemy.orm import * import testbase +from testbase import Table, Column import pickleable from sqlalchemy.orm.mapper import global_extensions from sqlalchemy.orm import util as ormutil @@ -462,7 +463,7 @@ class PassiveDeletesTest(UnitOfWorkTest): mytable = Table('mytable', metadata, Column('id', Integer, primary_key=True), Column('data', String(30)), - mysql_engine='InnoDB' + test_need_fk=True, ) myothertable = Table('myothertable', metadata, @@ -470,7 +471,7 @@ class PassiveDeletesTest(UnitOfWorkTest): Column('parent_id', Integer), Column('data', String(30)), ForeignKeyConstraint(['parent_id'],['mytable.id'], ondelete="CASCADE"), - mysql_engine='InnoDB' + test_need_fk=True, ) metadata.create_all() diff --git a/test/perf/cascade_speed.py b/test/perf/cascade_speed.py index a09e9dd6f7..fb3fb79709 100644 --- a/test/perf/cascade_speed.py +++ b/test/perf/cascade_speed.py @@ -1,4 +1,5 @@ from sqlalchemy import * +from testbase import Table, Column from timeit import Timer import sys @@ -87,4 +88,4 @@ if __name__ == "__main__": print "\nCreate backward associations" create_it = tt.create_back_assoc - tt.run(10) \ No newline at end of file + tt.run(10) diff --git a/test/perf/masseagerload.py b/test/perf/masseagerload.py index d4076f5ba9..dc3416089f 100644 --- a/test/perf/masseagerload.py +++ b/test/perf/masseagerload.py @@ -1,6 +1,7 @@ from testbase import PersistTest, AssertMixin import unittest, sys, os from sqlalchemy import * +from testbase import Table, Column import StringIO import testbase import gc diff --git a/test/perf/massload.py b/test/perf/massload.py index 9cbabea17a..560696f511 100644 --- a/test/perf/massload.py +++ b/test/perf/massload.py @@ -2,6 +2,7 @@ from testbase import PersistTest, AssertMixin import unittest, sys, os from sqlalchemy import * import sqlalchemy.orm.attributes as attributes +from testbase import Table, Column import StringIO import testbase import gc diff --git a/test/perf/massload2.py b/test/perf/massload2.py index 1506ca5030..d6424eb073 100644 --- a/test/perf/massload2.py +++ b/test/perf/massload2.py @@ -7,6 +7,7 @@ try: except: pass from sqlalchemy import * +from testbase import Table, Column import time metadata = create_engine('sqlite://', echo=True) diff --git a/test/perf/masssave.py b/test/perf/masssave.py index 8e4d5e3fff..98917462e8 100644 --- a/test/perf/masssave.py +++ b/test/perf/masssave.py @@ -2,6 +2,7 @@ from testbase import PersistTest, AssertMixin import unittest, sys, os from sqlalchemy import * import sqlalchemy.attributes as attributes +from testbase import Table, Column import StringIO import testbase import gc diff --git a/test/perf/poolload.py b/test/perf/poolload.py index 1b130f568b..29dcf87e92 100644 --- a/test/perf/poolload.py +++ b/test/perf/poolload.py @@ -4,6 +4,7 @@ from sqlalchemy import * import sqlalchemy.pool as pool +from testbase import Table, Column import psycopg2 as psycopg import thread,time psycopg = pool.manage(psycopg,pool_size=2,max_overflow=1, timeout=5, echo=True) @@ -33,4 +34,4 @@ for x in range(0,50): thread.start_new_thread(run, ()) while True: - time.sleep(5) \ No newline at end of file + time.sleep(5) diff --git a/test/perf/threaded_compile.py b/test/perf/threaded_compile.py index 3c521f2316..01418d2802 100644 --- a/test/perf/threaded_compile.py +++ b/test/perf/threaded_compile.py @@ -3,6 +3,7 @@ from sqlalchemy import * import thread, time, random from sqlalchemy.orm import mapperlib +from testbase import Table, Column meta = BoundMetaData('sqlite:///foo.db') diff --git a/test/perf/wsgi.py b/test/perf/wsgi.py index 7068de1fde..b77742d78f 100644 --- a/test/perf/wsgi.py +++ b/test/perf/wsgi.py @@ -4,6 +4,7 @@ from sqlalchemy import * import sqlalchemy.pool as pool import thread from sqlalchemy import exceptions +from testbase import Table, Column import logging logging.basicConfig() diff --git a/test/sql/case_statement.py b/test/sql/case_statement.py index 1865473951..802de6231e 100644 --- a/test/sql/case_statement.py +++ b/test/sql/case_statement.py @@ -1,6 +1,7 @@ import sys import testbase from sqlalchemy import * +from testbase import Table, Column class CaseTest(testbase.PersistTest): diff --git a/test/sql/constraints.py b/test/sql/constraints.py index d695e824c7..d84901a48c 100644 --- a/test/sql/constraints.py +++ b/test/sql/constraints.py @@ -1,5 +1,6 @@ import testbase from sqlalchemy import * +from testbase import Table, Column import sys class ConstraintTest(testbase.AssertMixin): diff --git a/test/sql/defaults.py b/test/sql/defaults.py index d4cb9e9f36..94adaa11d4 100644 --- a/test/sql/defaults.py +++ b/test/sql/defaults.py @@ -5,6 +5,7 @@ import sqlalchemy.schema as schema import testbase from sqlalchemy import * from sqlalchemy.orm import mapper, create_session +from testbase import Table, Column import sqlalchemy db = testbase.db diff --git a/test/sql/labels.py b/test/sql/labels.py index ee9fa6bc50..968e75dfc3 100644 --- a/test/sql/labels.py +++ b/test/sql/labels.py @@ -1,6 +1,6 @@ import testbase - from sqlalchemy import * +from testbase import Table, Column # TODO: either create a mock dialect with named paramstyle and a short identifier length, # or find a way to just use sqlite dialect and make those changes diff --git a/test/sql/query.py b/test/sql/query.py index 0d12aa1939..8597fbe756 100644 --- a/test/sql/query.py +++ b/test/sql/query.py @@ -8,6 +8,8 @@ import tables from sqlalchemy import * from sqlalchemy.engine import ResultProxy, RowProxy from sqlalchemy import exceptions +from testbase import Table, Column + class QueryTest(PersistTest): diff --git a/test/sql/quote.py b/test/sql/quote.py index 5259437fc7..1281b3d1ab 100644 --- a/test/sql/quote.py +++ b/test/sql/quote.py @@ -1,6 +1,8 @@ from testbase import PersistTest import testbase from sqlalchemy import * +from testbase import Table, Column + class QuoteTest(PersistTest): def setUpAll(self): diff --git a/test/sql/rowcount.py b/test/sql/rowcount.py index 95cab898c3..673a51bb0e 100644 --- a/test/sql/rowcount.py +++ b/test/sql/rowcount.py @@ -1,6 +1,8 @@ from sqlalchemy import * +from testbase import Table, Column import testbase + class FoundRowsTest(testbase.AssertMixin): """tests rowcount functionality""" def setUpAll(self): diff --git a/test/sql/select.py b/test/sql/select.py index 557527d056..157c623000 100644 --- a/test/sql/select.py +++ b/test/sql/select.py @@ -2,6 +2,7 @@ from testbase import PersistTest import testbase from sqlalchemy import * from sqlalchemy.databases import sqlite, postgres, mysql, oracle, firebird, mssql +from testbase import Table, Column import unittest, re, operator diff --git a/test/sql/selectable.py b/test/sql/selectable.py index b7ab91ee8f..dc992399e9 100755 --- a/test/sql/selectable.py +++ b/test/sql/selectable.py @@ -1,149 +1,148 @@ -"""tests that various From objects properly export their columns, as well as useable primary keys -and foreign keys. Full relational algebra depends on every selectable unit behaving -nicely with others..""" - -import testbase -import unittest, sys, datetime - - -db = testbase.db - -from sqlalchemy import * - -metadata = BoundMetaData(db) -table = Table('table1', metadata, - Column('col1', Integer, primary_key=True), - Column('col2', String(20)), - Column('col3', Integer), - Column('colx', Integer), - -) - -table2 = Table('table2', metadata, - Column('col1', Integer, primary_key=True), - Column('col2', Integer, ForeignKey('table1.col1')), - Column('col3', String(20)), - Column('coly', Integer), -) - -class SelectableTest(testbase.AssertMixin): - def testjoinagainstself(self): - jj = select([table.c.col1.label('bar_col1')]) - jjj = join(table, jj, table.c.col1==jj.c.bar_col1) - assert jjj.corresponding_column(jjj.c.table1_col1) is jjj.c.table1_col1 - - def testjoinagainstjoin(self): - j = outerjoin(table, table2, table.c.col1==table2.c.col2) - jj = select([ table.c.col1.label('bar_col1')],from_obj=[j]).alias('foo') - jjj = join(table, jj, table.c.col1==jj.c.bar_col1) - assert jjj.corresponding_column(jjj.c.table1_col1) is jjj.c.table1_col1 - - - def testtablealias(self): - a = table.alias('a') - - j = join(a, table2) - - criterion = a.c.col1 == table2.c.col2 - print - print str(j) - self.assert_(criterion.compare(j.onclause)) - - def testunion(self): - # tests that we can correspond a column in a Select statement with a certain Table, against - # a column in a Union where one of its underlying Selects matches to that same Table - u = select([table.c.col1, table.c.col2, table.c.col3, table.c.colx, null().label('coly')]).union( - select([table2.c.col1, table2.c.col2, table2.c.col3, null().label('colx'), table2.c.coly]) - ) - s1 = table.select(use_labels=True) - s2 = table2.select(use_labels=True) - print ["%d %s" % (id(c),c.key) for c in u.c] - c = u.corresponding_column(s1.c.table1_col2) - print "%d %s" % (id(c), c.key) - assert u.corresponding_column(s1.c.table1_col2) is u.c.col2 - assert u.corresponding_column(s2.c.table2_col2) is u.c.col2 - - def testaliasunion(self): - # same as testunion, except its an alias of the union - u = select([table.c.col1, table.c.col2, table.c.col3, table.c.colx, null().label('coly')]).union( - select([table2.c.col1, table2.c.col2, table2.c.col3, null().label('colx'), table2.c.coly]) - ).alias('analias') - s1 = table.select(use_labels=True) - s2 = table2.select(use_labels=True) - assert u.corresponding_column(s1.c.table1_col2) is u.c.col2 - assert u.corresponding_column(s2.c.table2_col2) is u.c.col2 - assert u.corresponding_column(s2.c.table2_coly) is u.c.coly - assert s2.corresponding_column(u.c.coly) is s2.c.table2_coly - - def testselectunion(self): - # like testaliasunion, but off a Select off the union. - u = select([table.c.col1, table.c.col2, table.c.col3, table.c.colx, null().label('coly')]).union( - select([table2.c.col1, table2.c.col2, table2.c.col3, null().label('colx'), table2.c.coly]) - ).alias('analias') - s = select([u]) - s1 = table.select(use_labels=True) - s2 = table2.select(use_labels=True) - assert s.corresponding_column(s1.c.table1_col2) is s.c.col2 - assert s.corresponding_column(s2.c.table2_col2) is s.c.col2 - - def testunionagainstjoin(self): - # same as testunion, except its an alias of the union - u = select([table.c.col1, table.c.col2, table.c.col3, table.c.colx, null().label('coly')]).union( - select([table2.c.col1, table2.c.col2, table2.c.col3, null().label('colx'), table2.c.coly]) - ).alias('analias') - j1 = table.join(table2) - assert u.corresponding_column(j1.c.table1_colx) is u.c.colx - assert j1.corresponding_column(u.c.colx) is j1.c.table1_colx - - def testjoin(self): - a = join(table, table2) - print str(a.select(use_labels=True)) - b = table2.alias('b') - j = join(a, b) - print str(j) - criterion = a.c.table1_col1 == b.c.col2 - self.assert_(criterion.compare(j.onclause)) - - def testselectalias(self): - a = table.select().alias('a') - print str(a.select()) - j = join(a, table2) - - criterion = a.c.col1 == table2.c.col2 - print - print str(j) - self.assert_(criterion.compare(j.onclause)) - - def testselectlabels(self): - a = table.select(use_labels=True) - print str(a.select()) - j = join(a, table2) - - criterion = a.c.table1_col1 == table2.c.col2 - print - print str(j) - self.assert_(criterion.compare(j.onclause)) - - def testcolumnlabels(self): - a = select([table.c.col1.label('acol1'), table.c.col2.label('acol2'), table.c.col3.label('acol3')]) - print str(a) - print [c for c in a.columns] - print str(a.select()) - j = join(a, table2) - criterion = a.c.acol1 == table2.c.col2 - print str(j) - self.assert_(criterion.compare(j.onclause)) - - def testselectaliaslabels(self): - a = table2.select(use_labels=True).alias('a') - print str(a.select()) - j = join(a, table) - - criterion = table.c.col1 == a.c.table2_col2 - print str(criterion) - print str(j.onclause) - self.assert_(criterion.compare(j.onclause)) - -if __name__ == "__main__": - testbase.main() - \ No newline at end of file +"""tests that various From objects properly export their columns, as well as +useable primary keys and foreign keys. Full relational algebra depends on +every selectable unit behaving nicely with others..""" + +import testbase +import unittest, sys, datetime +from sqlalchemy import * +from testbase import Table, Column + + +db = testbase.db +metadata = BoundMetaData(db) +table = Table('table1', metadata, + Column('col1', Integer, primary_key=True), + Column('col2', String(20)), + Column('col3', Integer), + Column('colx', Integer), + +) + +table2 = Table('table2', metadata, + Column('col1', Integer, primary_key=True), + Column('col2', Integer, ForeignKey('table1.col1')), + Column('col3', String(20)), + Column('coly', Integer), +) + +class SelectableTest(testbase.AssertMixin): + def testjoinagainstself(self): + jj = select([table.c.col1.label('bar_col1')]) + jjj = join(table, jj, table.c.col1==jj.c.bar_col1) + assert jjj.corresponding_column(jjj.c.table1_col1) is jjj.c.table1_col1 + + def testjoinagainstjoin(self): + j = outerjoin(table, table2, table.c.col1==table2.c.col2) + jj = select([ table.c.col1.label('bar_col1')],from_obj=[j]).alias('foo') + jjj = join(table, jj, table.c.col1==jj.c.bar_col1) + assert jjj.corresponding_column(jjj.c.table1_col1) is jjj.c.table1_col1 + + + def testtablealias(self): + a = table.alias('a') + + j = join(a, table2) + + criterion = a.c.col1 == table2.c.col2 + print + print str(j) + self.assert_(criterion.compare(j.onclause)) + + def testunion(self): + # tests that we can correspond a column in a Select statement with a certain Table, against + # a column in a Union where one of its underlying Selects matches to that same Table + u = select([table.c.col1, table.c.col2, table.c.col3, table.c.colx, null().label('coly')]).union( + select([table2.c.col1, table2.c.col2, table2.c.col3, null().label('colx'), table2.c.coly]) + ) + s1 = table.select(use_labels=True) + s2 = table2.select(use_labels=True) + print ["%d %s" % (id(c),c.key) for c in u.c] + c = u.corresponding_column(s1.c.table1_col2) + print "%d %s" % (id(c), c.key) + assert u.corresponding_column(s1.c.table1_col2) is u.c.col2 + assert u.corresponding_column(s2.c.table2_col2) is u.c.col2 + + def testaliasunion(self): + # same as testunion, except its an alias of the union + u = select([table.c.col1, table.c.col2, table.c.col3, table.c.colx, null().label('coly')]).union( + select([table2.c.col1, table2.c.col2, table2.c.col3, null().label('colx'), table2.c.coly]) + ).alias('analias') + s1 = table.select(use_labels=True) + s2 = table2.select(use_labels=True) + assert u.corresponding_column(s1.c.table1_col2) is u.c.col2 + assert u.corresponding_column(s2.c.table2_col2) is u.c.col2 + assert u.corresponding_column(s2.c.table2_coly) is u.c.coly + assert s2.corresponding_column(u.c.coly) is s2.c.table2_coly + + def testselectunion(self): + # like testaliasunion, but off a Select off the union. + u = select([table.c.col1, table.c.col2, table.c.col3, table.c.colx, null().label('coly')]).union( + select([table2.c.col1, table2.c.col2, table2.c.col3, null().label('colx'), table2.c.coly]) + ).alias('analias') + s = select([u]) + s1 = table.select(use_labels=True) + s2 = table2.select(use_labels=True) + assert s.corresponding_column(s1.c.table1_col2) is s.c.col2 + assert s.corresponding_column(s2.c.table2_col2) is s.c.col2 + + def testunionagainstjoin(self): + # same as testunion, except its an alias of the union + u = select([table.c.col1, table.c.col2, table.c.col3, table.c.colx, null().label('coly')]).union( + select([table2.c.col1, table2.c.col2, table2.c.col3, null().label('colx'), table2.c.coly]) + ).alias('analias') + j1 = table.join(table2) + assert u.corresponding_column(j1.c.table1_colx) is u.c.colx + assert j1.corresponding_column(u.c.colx) is j1.c.table1_colx + + def testjoin(self): + a = join(table, table2) + print str(a.select(use_labels=True)) + b = table2.alias('b') + j = join(a, b) + print str(j) + criterion = a.c.table1_col1 == b.c.col2 + self.assert_(criterion.compare(j.onclause)) + + def testselectalias(self): + a = table.select().alias('a') + print str(a.select()) + j = join(a, table2) + + criterion = a.c.col1 == table2.c.col2 + print + print str(j) + self.assert_(criterion.compare(j.onclause)) + + def testselectlabels(self): + a = table.select(use_labels=True) + print str(a.select()) + j = join(a, table2) + + criterion = a.c.table1_col1 == table2.c.col2 + print + print str(j) + self.assert_(criterion.compare(j.onclause)) + + def testcolumnlabels(self): + a = select([table.c.col1.label('acol1'), table.c.col2.label('acol2'), table.c.col3.label('acol3')]) + print str(a) + print [c for c in a.columns] + print str(a.select()) + j = join(a, table2) + criterion = a.c.acol1 == table2.c.col2 + print str(j) + self.assert_(criterion.compare(j.onclause)) + + def testselectaliaslabels(self): + a = table2.select(use_labels=True).alias('a') + print str(a.select()) + j = join(a, table) + + criterion = table.c.col1 == a.c.table2_col2 + print str(criterion) + print str(j.onclause) + self.assert_(criterion.compare(j.onclause)) + +if __name__ == "__main__": + testbase.main() + diff --git a/test/sql/testtypes.py b/test/sql/testtypes.py index 8406860ee7..5e272cfc93 100644 --- a/test/sql/testtypes.py +++ b/test/sql/testtypes.py @@ -4,9 +4,10 @@ import pickleable from sqlalchemy import * import string,datetime, re, sys, os import sqlalchemy.engine.url as url - import sqlalchemy.types from sqlalchemy.databases import mssql, oracle +from testbase import Table, Column + db = testbase.db diff --git a/test/sql/unicode.py b/test/sql/unicode.py index 15f4dd14c3..fb77a77b74 100644 --- a/test/sql/unicode.py +++ b/test/sql/unicode.py @@ -1,10 +1,11 @@ # coding: utf-8 -import testbase +"""verrrrry basic unicode column name testing""" +import testbase from sqlalchemy import * from sqlalchemy.orm import mapper, relation, create_session, eagerload +from testbase import Table, Column -"""verrrrry basic unicode column name testing""" class UnicodeSchemaTest(testbase.PersistTest): def setUpAll(self): diff --git a/test/tables.py b/test/tables.py index 8f00ea6acd..33ba858c21 100644 --- a/test/tables.py +++ b/test/tables.py @@ -2,7 +2,7 @@ from sqlalchemy import * import os import testbase - +from testbase import Table, Column ECHO = testbase.echo db = testbase.db @@ -11,14 +11,14 @@ metadata = BoundMetaData(db) users = Table('users', metadata, Column('user_id', Integer, Sequence('user_id_seq', optional=True), primary_key = True), Column('user_name', String(40)), - mysql_engine='innodb' + test_needs_acid=True, + test_needs_fk=True, ) addresses = Table('email_addresses', metadata, Column('address_id', Integer, Sequence('address_id_seq', optional=True), primary_key = True), Column('user_id', Integer, ForeignKey(users.c.user_id)), Column('email_address', String(40)), - ) orders = Table('orders', metadata, @@ -26,20 +26,17 @@ orders = Table('orders', metadata, Column('user_id', Integer, ForeignKey(users.c.user_id)), Column('description', String(50)), Column('isopen', Integer), - ) orderitems = Table('items', metadata, Column('item_id', INT, Sequence('items_id_seq', optional=True), primary_key = True), Column('order_id', INT, ForeignKey("orders")), Column('item_name', VARCHAR(50)), - ) keywords = Table('keywords', metadata, Column('keyword_id', Integer, Sequence('keyword_id_seq', optional=True), primary_key = True), Column('name', VARCHAR(50)), - ) userkeywords = Table('userkeywords', metadata, diff --git a/test/testbase.py b/test/testbase.py index 29c5c8ff34..4e3fc2d659 100644 --- a/test/testbase.py +++ b/test/testbase.py @@ -7,13 +7,14 @@ import sys import os, unittest, StringIO, re, ConfigParser, optparse sys.path.insert(0, os.path.join(os.getcwd(), 'lib')) import sqlalchemy -from sqlalchemy import sql, engine, pool, BoundMetaData +from sqlalchemy import sql, schema, engine, pool, BoundMetaData from sqlalchemy.orm import clear_mappers db = None metadata = None db_uri = None echo = True +table_options = {} # redefine sys.stdout so all those print statements go to the echo func local_stdout = sys.stdout @@ -64,6 +65,8 @@ firebird=firebird://sysdba:s@localhost/tmp/test.fdb parser.add_option("--reversetop", action="store_true", dest="topological", help="Reverse the collection ordering for topological sorts (helps reveal dependency issues)") parser.add_option("--serverside", action="store_true", dest="serverside", help="Turn on server side cursors for PG") parser.add_option("--require", action="append", dest="require", help="Require a particular driver or module version", default=[]) + parser.add_option("--mysql-engine", action="store", dest="mysql_engine", help="Use the specified MySQL storage engine for all tables, default is a db-default/InnoDB combo.", default=None) + parser.add_option("--table-option", action="append", dest="tableopts", help="Add a dialect-specific table option, key=value", default=[]) (options, args) = parser.parse_args() sys.argv[1:] = args @@ -106,6 +109,14 @@ firebird=firebird://sysdba:s@localhost/tmp/test.fdb if not db_uri: raise "Could not create engine. specify --db to test runner." + global table_options + for spec in options.tableopts: + key, value = spec.split('=') + table_options[key] = value + + if options.mysql_engine: + table_options['mysql_engine'] = options.mysql_engine + if not options.nothreadlocal: __import__('sqlalchemy.mods.threadlocal') sqlalchemy.mods.threadlocal.uninstall_plugin() @@ -188,6 +199,27 @@ def supported(*dbs): return lala return decorate +def Table(*args, **kw): + """A schema.Table wrapper/hook for dialect-specific tweaks.""" + + test_opts = dict([(k,kw.pop(k)) for k in kw.keys() + if k.startswith('test_')]) + + kw.update(table_options) + + if db.engine.name == 'mysql': + if 'mysql_engine' not in kw and 'mysql_type' not in kw: + if 'test_needs_fk' in test_opts or 'test_needs_acid' in test_opts: + kw['mysql_engine'] = 'InnoDB' + + return schema.Table(*args, **kw) + +def Column(*args, **kw): + """A schema.Column wrapper/hook for dialect-specific tweaks.""" + + # TODO: a Column that creates a Sequence automatically for PK columns, + # which would help Oracle tests + return schema.Column(*args, **kw) class PersistTest(unittest.TestCase): diff --git a/test/zblog/tables.py b/test/zblog/tables.py index f01f18921b..0ca66fb722 100644 --- a/test/zblog/tables.py +++ b/test/zblog/tables.py @@ -1,4 +1,5 @@ from sqlalchemy import * +from testbase import Table, Column metadata = MetaData() """application table metadata objects are described here."""