summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/databases
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2008-12-26 05:28:38 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2008-12-26 05:28:38 +0000
commit83a756c5415fad752933ed7f1aff69d2a184d618 (patch)
tree679b6d9ef7f383fc1c82fa4f27cc7591f015c116 /lib/sqlalchemy/databases
parent3ea2888b7f84ef7571c847991149c7372dd3db49 (diff)
downloadsqlalchemy-83a756c5415fad752933ed7f1aff69d2a184d618.tar.gz
- Reflected foreign keys will properly locate
their referenced column, even if the column was given a "key" attribute different from the reflected name. This is achieved via a new flag on ForeignKey/ForeignKeyConstraint called "link_to_name", if True means the given name is the referred-to column's name, not its assigned key. [ticket:650] - removed column types from sqlite doc, we aren't going to list out "implementation" types since they aren't significant and are less present in 0.6 - mysql will report on missing reflected foreign key targets in the same way as other dialects (we can improve that to be immediate within reflecttable(), but it should be within ForeignKeyConstraint()). - postgres dialect can reflect table with an include_columns list that doesn't include one or more primary key columns
Diffstat (limited to 'lib/sqlalchemy/databases')
-rw-r--r--lib/sqlalchemy/databases/access.py2
-rw-r--r--lib/sqlalchemy/databases/firebird.py2
-rw-r--r--lib/sqlalchemy/databases/informix.py2
-rw-r--r--lib/sqlalchemy/databases/maxdb.py2
-rw-r--r--lib/sqlalchemy/databases/mssql.py4
-rw-r--r--lib/sqlalchemy/databases/mysql.py16
-rw-r--r--lib/sqlalchemy/databases/oracle.py2
-rw-r--r--lib/sqlalchemy/databases/postgres.py11
-rw-r--r--lib/sqlalchemy/databases/sqlite.py2
-rw-r--r--lib/sqlalchemy/databases/sybase.py2
10 files changed, 21 insertions, 24 deletions
diff --git a/lib/sqlalchemy/databases/access.py b/lib/sqlalchemy/databases/access.py
index b5adc2015..7edf68de8 100644
--- a/lib/sqlalchemy/databases/access.py
+++ b/lib/sqlalchemy/databases/access.py
@@ -312,7 +312,7 @@ class AccessDialect(default.DefaultDialect):
continue
scols = [c.ForeignName for c in fk.Fields]
rcols = ['%s.%s' % (fk.Table, c.Name) for c in fk.Fields]
- table.append_constraint(schema.ForeignKeyConstraint(scols, rcols))
+ table.append_constraint(schema.ForeignKeyConstraint(scols, rcols, link_to_name=True))
finally:
dtbs.Close()
diff --git a/lib/sqlalchemy/databases/firebird.py b/lib/sqlalchemy/databases/firebird.py
index c42a2c7f5..2fa8ec190 100644
--- a/lib/sqlalchemy/databases/firebird.py
+++ b/lib/sqlalchemy/databases/firebird.py
@@ -539,7 +539,7 @@ class FBDialect(default.DefaultDialect):
fk[1].append(refspec)
for name, value in fks.iteritems():
- table.append_constraint(schema.ForeignKeyConstraint(value[0], value[1], name=name))
+ table.append_constraint(schema.ForeignKeyConstraint(value[0], value[1], name=name, link_to_name=True))
def do_execute(self, cursor, statement, parameters, **kwargs):
# kinterbase does not accept a None, but wants an empty list
diff --git a/lib/sqlalchemy/databases/informix.py b/lib/sqlalchemy/databases/informix.py
index 2a9327cf5..fa13d0d34 100644
--- a/lib/sqlalchemy/databases/informix.py
+++ b/lib/sqlalchemy/databases/informix.py
@@ -338,7 +338,7 @@ class InfoDialect(default.DefaultDialect):
fk[1].append(refspec)
for name, value in fks.iteritems():
- table.append_constraint(schema.ForeignKeyConstraint(value[0], value[1] , None ))
+ table.append_constraint(schema.ForeignKeyConstraint(value[0], value[1] , None, link_to_name=True ))
# PK
c = connection.execute("""select t1.constrname as cons_name , t1.constrtype as cons_type ,
diff --git a/lib/sqlalchemy/databases/maxdb.py b/lib/sqlalchemy/databases/maxdb.py
index dbe04f591..64b81482e 100644
--- a/lib/sqlalchemy/databases/maxdb.py
+++ b/lib/sqlalchemy/databases/maxdb.py
@@ -701,7 +701,7 @@ class MaxDBDialect(default.DefaultDialect):
autoload=True, autoload_with=connection,
**table_kw)
- constraint = schema.ForeignKeyConstraint(columns, referants,
+ constraint = schema.ForeignKeyConstraint(columns, referants, link_to_name=True,
**constraint_kw)
table.append_constraint(constraint)
diff --git a/lib/sqlalchemy/databases/mssql.py b/lib/sqlalchemy/databases/mssql.py
index ecf8b2462..5bf7f28af 100644
--- a/lib/sqlalchemy/databases/mssql.py
+++ b/lib/sqlalchemy/databases/mssql.py
@@ -1145,7 +1145,7 @@ class MSSQLDialect(default.DefaultDialect):
schema.Table(rtbl, table.metadata, schema=rschema, autoload=True, autoload_with=connection)
if rfknm != fknm:
if fknm:
- table.append_constraint(schema.ForeignKeyConstraint(scols, [_gen_fkref(table, s, t, c) for s, t, c in rcols], fknm))
+ table.append_constraint(schema.ForeignKeyConstraint(scols, [_gen_fkref(table, s, t, c) for s, t, c in rcols], fknm, link_to_name=True))
fknm, scols, rcols = (rfknm, [], [])
if not scol in scols:
scols.append(scol)
@@ -1153,7 +1153,7 @@ class MSSQLDialect(default.DefaultDialect):
rcols.append((rschema, rtbl, rcol))
if fknm and scols:
- table.append_constraint(schema.ForeignKeyConstraint(scols, [_gen_fkref(table, s, t, c) for s, t, c in rcols], fknm))
+ table.append_constraint(schema.ForeignKeyConstraint(scols, [_gen_fkref(table, s, t, c) for s, t, c in rcols], fknm, link_to_name=True))
class MSSQLDialect_pymssql(MSSQLDialect):
diff --git a/lib/sqlalchemy/databases/mysql.py b/lib/sqlalchemy/databases/mysql.py
index e22f242ea..86fb7b247 100644
--- a/lib/sqlalchemy/databases/mysql.py
+++ b/lib/sqlalchemy/databases/mysql.py
@@ -2326,23 +2326,19 @@ class MySQLSchemaReflector(object):
autoload=True, autoload_with=connection)
ref_names = spec['foreign']
- if not set(ref_names).issubset(
- set(c.name for c in ref_table.c)):
- raise exc.InvalidRequestError(
- "Foreign key columns (%s) are not present on "
- "foreign table %s" %
- (', '.join(ref_names), ref_table.fullname))
- ref_columns = [ref_table.c[name] for name in ref_names]
+
+ if ref_schema:
+ refspec = [".".join([ref_schema, ref_name, column]) for column in ref_names]
+ else:
+ refspec = [".".join([ref_name, column]) for column in ref_names]
con_kw = {}
for opt in ('name', 'onupdate', 'ondelete'):
if spec.get(opt, False):
con_kw[opt] = spec[opt]
- key = schema.ForeignKeyConstraint([], [], **con_kw)
+ key = schema.ForeignKeyConstraint(loc_names, refspec, link_to_name=True, **con_kw)
table.append_constraint(key)
- for pair in zip(loc_names, ref_columns):
- key.append_element(*pair)
def _set_options(self, table, line):
"""Apply safe reflected table options to a ``Table``.
diff --git a/lib/sqlalchemy/databases/oracle.py b/lib/sqlalchemy/databases/oracle.py
index 66e83ec2f..aed070f2e 100644
--- a/lib/sqlalchemy/databases/oracle.py
+++ b/lib/sqlalchemy/databases/oracle.py
@@ -680,7 +680,7 @@ class OracleDialect(default.DefaultDialect):
fk[1].append(refspec)
for name, value in fks.iteritems():
- table.append_constraint(schema.ForeignKeyConstraint(value[0], value[1], name=name))
+ table.append_constraint(schema.ForeignKeyConstraint(value[0], value[1], name=name, link_to_name=True))
class _OuterJoinColumn(sql.ClauseElement):
diff --git a/lib/sqlalchemy/databases/postgres.py b/lib/sqlalchemy/databases/postgres.py
index 0a6c12f9b..273f5859e 100644
--- a/lib/sqlalchemy/databases/postgres.py
+++ b/lib/sqlalchemy/databases/postgres.py
@@ -577,10 +577,11 @@ class PGDialect(default.DefaultDialect):
c = connection.execute(t, table=table_oid)
for row in c.fetchall():
pk = row[0]
- col = table.c[pk]
- table.primary_key.add(col)
- if col.default is None:
- col.autoincrement = False
+ if pk in table.c:
+ col = table.c[pk]
+ table.primary_key.add(col)
+ if col.default is None:
+ col.autoincrement = False
# Foreign keys
FK_SQL = """
@@ -617,7 +618,7 @@ class PGDialect(default.DefaultDialect):
for column in referred_columns:
refspec.append(".".join([referred_table, column]))
- table.append_constraint(schema.ForeignKeyConstraint(constrained_columns, refspec, conname))
+ table.append_constraint(schema.ForeignKeyConstraint(constrained_columns, refspec, conname, link_to_name=True))
# Indexes
IDX_SQL = """
diff --git a/lib/sqlalchemy/databases/sqlite.py b/lib/sqlalchemy/databases/sqlite.py
index 6eabca1a9..270e067f4 100644
--- a/lib/sqlalchemy/databases/sqlite.py
+++ b/lib/sqlalchemy/databases/sqlite.py
@@ -522,7 +522,7 @@ class SQLiteDialect(default.DefaultDialect):
if refspec not in fk[1]:
fk[1].append(refspec)
for name, value in fks.iteritems():
- table.append_constraint(schema.ForeignKeyConstraint(value[0], value[1]))
+ table.append_constraint(schema.ForeignKeyConstraint(value[0], value[1], link_to_name=True))
# check for UNIQUE indexes
c = connection.execute("%sindex_list(%s)" % (pragma, qtable))
unique_indexes = []
diff --git a/lib/sqlalchemy/databases/sybase.py b/lib/sqlalchemy/databases/sybase.py
index 75b208056..652f6d8a7 100644
--- a/lib/sqlalchemy/databases/sybase.py
+++ b/lib/sqlalchemy/databases/sybase.py
@@ -619,7 +619,7 @@ class SybaseSQLDialect(default.DefaultDialect):
foreignKeys[primary_table][1].append('%s.%s'%(primary_table, primary_column))
for primary_table in foreignKeys.keys():
#table.append_constraint(schema.ForeignKeyConstraint(['%s.%s'%(foreign_table, foreign_column)], ['%s.%s'%(primary_table,primary_column)]))
- table.append_constraint(schema.ForeignKeyConstraint(foreignKeys[primary_table][0], foreignKeys[primary_table][1]))
+ table.append_constraint(schema.ForeignKeyConstraint(foreignKeys[primary_table][0], foreignKeys[primary_table][1], link_to_name=True))
if not found_table:
raise exc.NoSuchTableError(table.name)