We propose a novel approach to the classical view update problem. The view update problem arises from the fact that modifications to a database view may not correspond uniquely to modifications on the underlying database; we need a means of determining an “update policy ” that guides how view updates are reflected in the database. Our approach is to define a bi-directional query language, in which every expression can be read both (from left to right) as a view definition and (from right to left) as an update policy. The primitives of this language are based on standard relational operators. Its type system, which includes recordlevel predicates and functional dependencies, plays a crucial role in guaranteeing that update policies are well-behaved, in a precise sense, and that they are total—i.e., able to handle arbitrary changes to the view.