table.append_constraint(PrimaryKeyConstraint(...))
- Column.bind (get via column.table.bind)
- Column.metadata (get via column.table.metadata)
-
+ - Column.sequence (use column.default)
+
- The use_alter flag on ForeignKey is now a shortcut option
for operations that can be hand-constructed using the
DDL() event system. A side effect of this refactor is
--- /dev/null
+=================
+PYTHON 3 SUPPORT
+=================
+
+Current Python 3k support in SQLAlchemy is provided by a customized
+2to3 script which wraps Python's 2to3 tool.
+
+This document will refer to the Python 2.6 interpreter binary as
+"python26" and the Python 3.xx interpreter binary as "python3".
+
+To build the Python 3K version, use the Python 2.6 interpreter to
+run the 2to3 script on the lib/ directory, and optionally the test/
+directory. The -w flag indicates that the new files should be
+written.
+
+ python26 sa2to3.py ./lib/ ./test/ -w
+
+You now have a Python 3 version of SQLAlchemy in lib/.
+
+
+Running Tests
+-------------
+
+The unit test runner, described in README.unittests, is built on
+Nose, and uses a plugin that is ordinarily installed using setuptools
+entry points. At the time of this writing setuptools isn't available
+for Python 3 although the "Distribute" project does seem to provide support.
+Additionally, Nose itself is only available in an old version for Python 3,
+which is available at http://bitbucket.org/jpellerin/nose3/ .
+
+To run the unit tests using the old version of nose and without the usage of
+setuptools, use the "sqla_nose.py" script:
+
+ python3 sqla_nose.py
+
+When running with Python 3, lots of debug output is dumped to the console.
+This is due to hacking around the old version of Nose to support the
+SQLAlchemy test plugin without setuptools (details at
+http://groups.google.com/group/nose-dev/browse_thread/thread/c6a25531baaa2531).
\ No newline at end of file
class _LOBMixin(object):
def result_processor(self, dialect):
- super_process = super(_LOBMixin, self).result_processor(dialect)
if not dialect.auto_convert_lobs:
- return super_process
+ # return the cx_oracle.LOB directly.
+ # don't even call super.result_processor here.
+ return None
+
+ super_process = super(_LOBMixin, self).result_processor(dialect)
lob = dialect.dbapi.LOB
def process(value):
if isinstance(value, lob):
self._table_events = set()
if self.default is not None:
- if isinstance(self.default, ColumnDefault):
+ if isinstance(self.default, (ColumnDefault, Sequence)):
args.append(self.default)
else:
args.append(ColumnDefault(self.default))
def _set_parent(self, column):
super(Sequence, self)._set_parent(column)
- column.sequence = self
+# column.sequence = self
column._on_table_attach(self._set_table)
from sqlalchemy.test.testing import assert_raises, assert_raises_message
import pickle
-from sqlalchemy import Integer, String, UniqueConstraint, CheckConstraint, ForeignKey, MetaData
-from sqlalchemy.test.schema import Table
-from sqlalchemy.test.schema import Column
+from sqlalchemy import Integer, String, UniqueConstraint, CheckConstraint, ForeignKey, MetaData, Sequence
+from sqlalchemy.test.schema import Table, Column
from sqlalchemy import schema
import sqlalchemy as tsa
from sqlalchemy.test import TestBase, ComparesTables, AssertsCompiledSQL, testing, engines
assert str(e) == "Table 'table1' is already defined for this MetaData instance. Specify 'useexisting=True' to redefine options and columns on an existing Table object."
finally:
metadata.drop_all()
-
+
@testing.exclude('mysql', '<', (4, 1, 1), 'early types are squirrely')
def test_to_metadata(self):
meta = MetaData()
)
table2 = Table('othertable', meta,
- Column('id', Integer, primary_key=True),
+ Column('id', Integer, Sequence('foo_seq'), primary_key=True),
Column('myid', Integer, ForeignKey('mytable.myid')),
test_needs_fk=True,
)
assert str(table_c.c.foo.server_onupdate.arg) == 'q'
assert str(table_c.c.bar.default.arg) == 'y'
assert getattr(table_c.c.bar.onupdate.arg, 'arg', table_c.c.bar.onupdate.arg) == 'z'
-
+ assert isinstance(table2_c.c.id.default, Sequence)
+
# constraints dont get reflected for any dialect right now
if has_constraints:
for c in table_c.c.description.constraints:
class Master(Base):
__tablename__ = 'master'
- id = Column(Integer, primary_key=True)
+ id = Column(Integer, primary_key=True, test_needs_autoincrement=True)
class Detail(Base):
__tablename__ = 'detail'
- id = Column(Integer, primary_key=True)
+ id = Column(Integer, primary_key=True, test_needs_autoincrement=True)
master_id = Column(None, ForeignKey(Master.id))
master = relation(Master)
sess = create_session()
def go():
eq_(
- sess.query(Parent).join(Parent.children).options(contains_eager(Parent.children)).all(),
+ sess.query(Parent).join(Parent.children).options(contains_eager(Parent.children)).\
+ order_by(Parent.data, Sub.data).all(),
[
Parent(data='p1', children=[Sub(data='s1'), Sub(data='s2'), Sub(data='s3')]),
Parent(data='p2', children=[Sub(data='s4'), Sub(data='s5')])
@classmethod
def define_tables(cls, metadata):
Table('t1', metadata,
- Column('id', sa.Integer, primary_key=True),
+ Column('id', sa.Integer, primary_key=True, test_needs_autoincrement=True),
Column('data', sa.Binary),
)
@testing.fails_on('maxdb', 'FIXME: unknown')
def teststandalone2(self):
- x = cartitems.c.cart_id.sequence.execute()
+ x = cartitems.c.cart_id.default.execute()
self.assert_(1 <= x <= 4)
@classmethod