diff --git a/microcosm_postgres/temporary/copy.py b/microcosm_postgres/temporary/copy.py
index <HASH>..<HASH> 100644
--- a/microcosm_postgres/temporary/copy.py
+++ b/microcosm_postgres/temporary/copy.py
@@ -4,6 +4,34 @@ Copy a table.
 """
 from sqlalchemy import Table
 
+from microcosm_postgres.types import Serial
+
+
+def copy_column(column, schema):
+    """
+    Safely create a copy of a column.
+
+    """
+    return column.copy(schema=schema)
+
+
+def should_copy(column):
+    """
+    Determine if a column should be copied.
+
+    """
+    if not isinstance(column.type, Serial):
+        return True
+
+    if column.nullable:
+        return True
+
+    if not column.server_default:
+        return True
+
+    # do not create temporary serial values; they will be defaulted on upsert/insert
+    return False
+
 
 def copy_table(from_table, name):
     """
@@ -20,8 +48,9 @@ def copy_table(from_table, name):
     schema = metadata.schema
 
     columns = [
-        column.copy(schema=schema)
+        copy_column(column, schema)
         for column in from_table.columns
+        if should_copy(column)
     ]
 
     return Table(
Handle serial values on temporary table creation

Do not copy serial columns because they will be generated automatically
if and only they are omitted from the insert().select_from().