mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-06-04 06:48:27 -04:00
7c6c1b99c2
2. compiler names changed to be less verbose, unused classes removed. 3. Methods on Dialect which return compilers, schema generators, identifier preparers have changed to direct class references, typically on the Dialect class itself or optionally as attributes on an individual Dialect instance if conditional behavior is needed. This takes away the need for Dialect subclasses to know how to instantiate these objects, and also reduces method overhead by one call for each one. 4. as a result of 3., some internal signatures have changed for things like compiler() (now statement_compiler()), preparer(), etc., mostly in that the dialect needs to be passed explicitly as the first argument (since they are just class references now). The compiler() method on Engine and Connection is now also named statement_compiler(), but as before does not take the dialect as an argument. 5. changed _process_row function on RowProxy to be a class reference, cuts out 50K method calls from insertspeed.py
205 lines
7.5 KiB
Python
205 lines
7.5 KiB
Python
import testbase
|
|
from sqlalchemy import *
|
|
from testlib import *
|
|
|
|
class ConstraintTest(AssertMixin):
|
|
|
|
def setUp(self):
|
|
global metadata
|
|
metadata = MetaData(testbase.db)
|
|
|
|
def tearDown(self):
|
|
metadata.drop_all()
|
|
|
|
def test_constraint(self):
|
|
employees = Table('employees', metadata,
|
|
Column('id', Integer),
|
|
Column('soc', String(40)),
|
|
Column('name', String(30)),
|
|
PrimaryKeyConstraint('id', 'soc')
|
|
)
|
|
elements = Table('elements', metadata,
|
|
Column('id', Integer),
|
|
Column('stuff', String(30)),
|
|
Column('emp_id', Integer),
|
|
Column('emp_soc', String(40)),
|
|
PrimaryKeyConstraint('id', name='elements_primkey'),
|
|
ForeignKeyConstraint(['emp_id', 'emp_soc'], ['employees.id', 'employees.soc'])
|
|
)
|
|
metadata.create_all()
|
|
|
|
def test_circular_constraint(self):
|
|
a = Table("a", metadata,
|
|
Column('id', Integer, primary_key=True),
|
|
Column('bid', Integer),
|
|
ForeignKeyConstraint(["bid"], ["b.id"], name="afk")
|
|
)
|
|
b = Table("b", metadata,
|
|
Column('id', Integer, primary_key=True),
|
|
Column("aid", Integer),
|
|
ForeignKeyConstraint(["aid"], ["a.id"], use_alter=True, name="bfk")
|
|
)
|
|
metadata.create_all()
|
|
|
|
def test_circular_constraint_2(self):
|
|
a = Table("a", metadata,
|
|
Column('id', Integer, primary_key=True),
|
|
Column('bid', Integer, ForeignKey("b.id")),
|
|
)
|
|
b = Table("b", metadata,
|
|
Column('id', Integer, primary_key=True),
|
|
Column("aid", Integer, ForeignKey("a.id", use_alter=True, name="bfk")),
|
|
)
|
|
metadata.create_all()
|
|
|
|
@testing.unsupported('mysql')
|
|
def test_check_constraint(self):
|
|
foo = Table('foo', metadata,
|
|
Column('id', Integer, primary_key=True),
|
|
Column('x', Integer),
|
|
Column('y', Integer),
|
|
CheckConstraint('x>y'))
|
|
bar = Table('bar', metadata,
|
|
Column('id', Integer, primary_key=True),
|
|
Column('x', Integer, CheckConstraint('x>7')),
|
|
Column('z', Integer)
|
|
)
|
|
|
|
metadata.create_all()
|
|
foo.insert().execute(id=1,x=9,y=5)
|
|
try:
|
|
foo.insert().execute(id=2,x=5,y=9)
|
|
assert False
|
|
except exceptions.SQLError:
|
|
assert True
|
|
|
|
bar.insert().execute(id=1,x=10)
|
|
try:
|
|
bar.insert().execute(id=2,x=5)
|
|
assert False
|
|
except exceptions.SQLError:
|
|
assert True
|
|
|
|
def test_unique_constraint(self):
|
|
foo = Table('foo', metadata,
|
|
Column('id', Integer, primary_key=True),
|
|
Column('value', String(30), unique=True))
|
|
bar = Table('bar', metadata,
|
|
Column('id', Integer, primary_key=True),
|
|
Column('value', String(30)),
|
|
Column('value2', String(30)),
|
|
UniqueConstraint('value', 'value2', name='uix1')
|
|
)
|
|
metadata.create_all()
|
|
foo.insert().execute(id=1, value='value1')
|
|
foo.insert().execute(id=2, value='value2')
|
|
bar.insert().execute(id=1, value='a', value2='a')
|
|
bar.insert().execute(id=2, value='a', value2='b')
|
|
try:
|
|
foo.insert().execute(id=3, value='value1')
|
|
assert False
|
|
except exceptions.SQLError:
|
|
assert True
|
|
try:
|
|
bar.insert().execute(id=3, value='a', value2='b')
|
|
assert False
|
|
except exceptions.SQLError:
|
|
assert True
|
|
|
|
def test_index_create(self):
|
|
employees = Table('employees', metadata,
|
|
Column('id', Integer, primary_key=True),
|
|
Column('first_name', String(30)),
|
|
Column('last_name', String(30)),
|
|
Column('email_address', String(30)))
|
|
employees.create()
|
|
|
|
i = Index('employee_name_index',
|
|
employees.c.last_name, employees.c.first_name)
|
|
i.create()
|
|
assert i in employees.indexes
|
|
|
|
i2 = Index('employee_email_index',
|
|
employees.c.email_address, unique=True)
|
|
i2.create()
|
|
assert i2 in employees.indexes
|
|
|
|
def test_index_create_camelcase(self):
|
|
"""test that mixed-case index identifiers are legal"""
|
|
employees = Table('companyEmployees', metadata,
|
|
Column('id', Integer, primary_key=True),
|
|
Column('firstName', String(30)),
|
|
Column('lastName', String(30)),
|
|
Column('emailAddress', String(30)))
|
|
|
|
employees.create()
|
|
|
|
i = Index('employeeNameIndex',
|
|
employees.c.lastName, employees.c.firstName)
|
|
i.create()
|
|
|
|
i = Index('employeeEmailIndex',
|
|
employees.c.emailAddress, unique=True)
|
|
i.create()
|
|
|
|
# Check that the table is useable. This is mostly for pg,
|
|
# which can be somewhat sticky with mixed-case identifiers
|
|
employees.insert().execute(firstName='Joe', lastName='Smith', id=0)
|
|
ss = employees.select().execute().fetchall()
|
|
assert ss[0].firstName == 'Joe'
|
|
assert ss[0].lastName == 'Smith'
|
|
|
|
def test_index_create_inline(self):
|
|
"""Test indexes defined with tables"""
|
|
|
|
events = Table('events', metadata,
|
|
Column('id', Integer, primary_key=True),
|
|
Column('name', String(30), index=True, unique=True),
|
|
Column('location', String(30), index=True),
|
|
Column('sport', String(30)),
|
|
Column('announcer', String(30)),
|
|
Column('winner', String(30)))
|
|
|
|
Index('sport_announcer', events.c.sport, events.c.announcer, unique=True)
|
|
Index('idx_winners', events.c.winner)
|
|
|
|
index_names = [ ix.name for ix in events.indexes ]
|
|
assert 'ix_events_name' in index_names
|
|
assert 'ix_events_location' in index_names
|
|
assert 'sport_announcer' in index_names
|
|
assert 'idx_winners' in index_names
|
|
assert len(index_names) == 4
|
|
|
|
capt = []
|
|
connection = testbase.db.connect()
|
|
# TODO: hacky, put a real connection proxy in
|
|
ex = connection._Connection__execute
|
|
def proxy(context):
|
|
capt.append(context.statement)
|
|
capt.append(repr(context.parameters))
|
|
ex(context)
|
|
connection._Connection__execute = proxy
|
|
schemagen = testbase.db.dialect.schemagenerator(testbase.db.dialect, connection)
|
|
schemagen.traverse(events)
|
|
|
|
assert capt[0].strip().startswith('CREATE TABLE events')
|
|
|
|
s = set([capt[x].strip() for x in [2,4,6,8]])
|
|
|
|
assert s == set([
|
|
'CREATE UNIQUE INDEX ix_events_name ON events (name)',
|
|
'CREATE INDEX ix_events_location ON events (location)',
|
|
'CREATE UNIQUE INDEX sport_announcer ON events (sport, announcer)',
|
|
'CREATE INDEX idx_winners ON events (winner)'
|
|
])
|
|
|
|
# verify that the table is functional
|
|
events.insert().execute(id=1, name='hockey finals', location='rink',
|
|
sport='hockey', announcer='some canadian',
|
|
winner='sweden')
|
|
ss = events.select().execute().fetchall()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
testbase.main()
|