A table object is always in one of two states: closed or open. It becomes open when quince verifies that its target exists and conforms to it, and it is closed whenever quince considers this to be unverified.
When you construct a table
mytable, you specify
its site. Its target might or might not exist already, and if it exists
it might or might not conform to
constructor doesn't communicate with the DBMS, so none of these things
are confirmed. Therefore
mytable is in the closed
A call to
tries to get
mytable into the open state, by
communicating with the DBMS and:
mytable's target doesn't exist, creating a target that conforms to
mytable. That includes:
mytable's value mapper expects.
mytable's target exists, interrogating its metadata to verify that it conforms to
mytable, and throwing a
table_mismatch_exceptionif it doesn't.
returns rather than throws,
mytable is open.
Tables have methods that let you specify a primary key, indexes (with or
without uniqueness constraints), and foreign key constraints. None of these
methods takes immediate action. They specify actions in advance, which
a subsequent call to open() will carry out, if it
decides to create the target  . So the time to call these methods is before the first call
As a defence against programmer error, they check that
is closed, and throw a
mytable is open, you can treat it as a
query, and you can manipulate its data. All the querying and manipulation
operations require a conforming target, so they all check that
is open, and throw a
if it isn't.
Occasionally you may want to rename an SQL table, or change its “shape”,
i.e. add or remove columns, or rename columns, or change their types. This
is called an alteration. If the target conformed to
mytable before an alteration, then it will not
conform afterwards; and conversely, if it conforms afterwards then it must
not have conformed before. But quince's policy on state is simple: the
table stays closed throughout. Closed state is a precondition and a postcondition
of every alteration. (If you try to alter an open table it will throw
the table will stay open and unaltered.)
So you can alter a table before you ever open it, but that is not always
sufficient. Some situations call for a complex “schema evolution”
process, involving several stages of alteration, query/manipulation, alteration,
query/manipulation, ... . You need to
open() the table before each query/manipulation
step, but then the next alteration step needs it to be closed. So tables
method, for that specific purpose.
And that's the only purpose of
close(). Don't think of closing a table as an
obligation, like closing an open file descriptor, to release some valuable
resource. There is no such resource; all
close() does is flip a flag.
are the only actions that change a table's open/closed state.
As a further defence against programmer error,
close() check that you aren't calling them redundantly.
on an open table throws a
on a closed table throws a
Finally, every table has the methods
drop_if_exists(), which remove the target outright. The
table object must be closed before these operations, and it remains closed.
DROP TABLE, and
DROP TABLE IF EXISTS.
So if the target doesn't exist,
drop() will throw a
will do nothing.
 You can't alter the primary key, indexes, or foreign key constraints on an SQL table that already exists. That is a limitation of quince 1.0.