diff --git a/IPython/core/history.py b/IPython/core/history.py
index 9ae70f6..b10ac42 100644
--- a/IPython/core/history.py
+++ b/IPython/core/history.py
@@ -17,12 +17,15 @@ import atexit
 import datetime
 import os
 import re
-import sqlite3
+try:
+    import sqlite3
+except ImportError:
+    sqlite3 = None
 import threading
 
 # Our own packages
 from IPython.config.configurable import Configurable
-
+from IPython.external.decorator import decorator
 from IPython.testing.skipdoctest import skip_doctest
 from IPython.utils import io
 from IPython.utils.path import locate_profile
@@ -33,6 +36,30 @@ from IPython.utils.warn import warn
 # Classes and functions
 #-----------------------------------------------------------------------------
 
+class DummyDB(object):
+    """Dummy DB that will act as a black hole for history.
+    
+    Only used in the absence of sqlite"""
+    def execute(*args, **kwargs):
+        return []
+    
+    def commit(self, *args, **kwargs):
+        pass
+    
+    def __enter__(self, *args, **kwargs):
+        pass
+    
+    def __exit__(self, *args, **kwargs):
+        pass
+    
+@decorator
+def needs_sqlite(f,*a,**kw):
+    """return an empty list in the absence of sqlite"""
+    if sqlite3 is None:
+        return []
+    else:
+        return f(*a,**kw)
+
 class HistoryAccessor(Configurable):
     """Access the history database without adding to it.
     
@@ -42,7 +69,10 @@ class HistoryAccessor(Configurable):
     hist_file = Unicode(config=True)
 
     # The SQLite database
-    db = Instance(sqlite3.Connection)
+    if sqlite3:
+        db = Instance(sqlite3.Connection)
+    else:
+        db = Instance(DummyDB)
     
     def __init__(self, profile='default', hist_file=u'', shell=None, config=None, **traits):
         """Create a new history accessor.
@@ -67,6 +97,11 @@ class HistoryAccessor(Configurable):
             # No one has set the hist_file, yet.
             self.hist_file = self._get_hist_file_name(profile)
 
+        if sqlite3 is None:
+            warn("IPython History requires SQLite, your history will not be saved\n")
+            self.db = DummyDB()
+            return
+        
         try:
             self.init_db()
         except sqlite3.DatabaseError:
@@ -146,6 +181,7 @@ class HistoryAccessor(Configurable):
             return ((ses, lin, (inp, out)) for ses, lin, inp, out in cur)
         return cur
 
+    @needs_sqlite
     def get_session_info(self, session=0):
         """get info about a session
 
@@ -351,7 +387,7 @@ class HistoryManager(HistoryAccessor):
         self.save_thread.start()
 
         self.new_session()
-    
+
     def _get_hist_file_name(self, profile=None):
         """Get default history file name based on the Shell's profile.
         
@@ -360,6 +396,7 @@ class HistoryManager(HistoryAccessor):
         profile_dir = self.shell.profile_dir.location
         return os.path.join(profile_dir, 'history.sqlite')
     
+    @needs_sqlite
     def new_session(self, conn=None):
         """Get a new session number."""
         if conn is None:
@@ -537,6 +574,7 @@ class HistoryManager(HistoryAccessor):
                 conn.execute("INSERT INTO output_history VALUES (?, ?, ?)",
                                 (self.session_number,)+line)
 
+    @needs_sqlite
     def writeout_cache(self, conn=None):
         """Write any entries in the cache to the database."""
         if conn is None:
@@ -581,6 +619,7 @@ class HistorySavingThread(threading.Thread):
         self.history_manager = history_manager
         atexit.register(self.stop)
 
+    @needs_sqlite
     def run(self):
         # We need a separate db connection per thread:
         try:
diff --git a/IPython/core/tests/test_magic.py b/IPython/core/tests/test_magic.py
index e4ebde9..0cf5d56 100644
--- a/IPython/core/tests/test_magic.py
+++ b/IPython/core/tests/test_magic.py
@@ -55,7 +55,8 @@ def test_magic_parse_options():
         expected = path
     nt.assert_equals(opts['f'], expected)
 
-    
+
+@dec.skip_without('sqlite3')
 def doctest_hist_f():
     """Test %hist -f with temporary filename.
 
@@ -69,6 +70,7 @@ def doctest_hist_f():
     """
 
 
+@dec.skip_without('sqlite3')
 def doctest_hist_r():
     """Test %hist -r
 
@@ -86,6 +88,8 @@ def doctest_hist_r():
     %hist -r 2
     """
 
+
+@dec.skip_without('sqlite3')
 def doctest_hist_op():
     """Test %hist -op
 
@@ -151,7 +155,9 @@ def doctest_hist_op():
     's'
     >>> 
     """
-  
+
+
+@dec.skip_without('sqlite3')
 def test_macro():
     ip = get_ipython()
     ip.history_manager.reset()   # Clear any existing history.
@@ -164,6 +170,8 @@ def test_macro():
     # List macros.
     assert "test" in ip.magic("macro")
 
+
+@dec.skip_without('sqlite3')
 def test_macro_run():
     """Test that we can run a multi-line macro successfully."""
     ip = get_ipython()
diff --git a/IPython/core/tests/test_run.py b/IPython/core/tests/test_run.py
index 6a823df..af52125 100644
--- a/IPython/core/tests/test_run.py
+++ b/IPython/core/tests/test_run.py
@@ -169,9 +169,13 @@ class TestMagicRunSimple(tt.TempFileMixin):
                "        print 'object A deleted'\n"
                "a = A()\n")
         self.mktmp(py3compat.doctest_refactor_print(src))
-        tt.ipexec_validate(self.fname, 'object A deleted')
-
-    @dec.skip_known_failure
+        if dec.module_not_available('sqlite3'):
+            err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
+        else:
+            err = None
+        tt.ipexec_validate(self.fname, 'object A deleted', err)
+    
+    @dec.skip_known_failure 
     def test_aggressive_namespace_cleanup(self):
         """Test that namespace cleanup is not too aggressive GH-238
 
@@ -207,4 +211,8 @@ ARGV 1-: ['C-third']
 tclass.py: deleting object: C-second
 tclass.py: deleting object: C-third
 """
-        tt.ipexec_validate(self.fname, out)
+        if dec.module_not_available('sqlite3'):
+            err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
+        else:
+            err = None
+        tt.ipexec_validate(self.fname, out, err)
diff --git a/IPython/parallel/controller/sqlitedb.py b/IPython/parallel/controller/sqlitedb.py
index 80806e8..8b5d724 100644
--- a/IPython/parallel/controller/sqlitedb.py
+++ b/IPython/parallel/controller/sqlitedb.py
@@ -16,7 +16,10 @@ import os
 import cPickle as pickle
 from datetime import datetime
 
-import sqlite3
+try:
+    import sqlite3
+except ImportError:
+    sqlite3 = None
 
 from zmq.eventloop import ioloop
 
@@ -99,7 +102,10 @@ class SQLiteDB(BaseDB):
         in tasks from previous sessions being available via Clients' db_query and
         get_result methods.""")
 
-    _db = Instance('sqlite3.Connection')
+    if sqlite3 is not None:
+        _db = Instance('sqlite3.Connection')
+    else:
+        _db = None
     # the ordered list of column names
     _keys = List(['msg_id' ,
             'header' ,
@@ -145,6 +151,8 @@ class SQLiteDB(BaseDB):
 
     def __init__(self, **kwargs):
         super(SQLiteDB, self).__init__(**kwargs)
+        if sqlite3 is None:
+            raise ImportError("SQLiteDB requires sqlite3")
         if not self.table:
             # use session, and prefix _, since starting with # is illegal
             self.table = '_'+self.session.replace('-','_')
diff --git a/IPython/parallel/tests/test_db.py b/IPython/parallel/tests/test_db.py
index 4711d9a..3bdc1e9 100644
--- a/IPython/parallel/tests/test_db.py
+++ b/IPython/parallel/tests/test_db.py
@@ -24,13 +24,12 @@ import time
 from datetime import datetime, timedelta
 from unittest import TestCase
 
-from nose import SkipTest
-
 from IPython.parallel import error
 from IPython.parallel.controller.dictdb import DictDB
 from IPython.parallel.controller.sqlitedb import SQLiteDB
 from IPython.parallel.controller.hub import init_record, empty_record
 
+from IPython.testing import decorators as dec
 from IPython.zmq.session import Session
 
 
@@ -171,8 +170,11 @@ class TestDictBackend(TestCase):
         self.db.drop_matching_records(query)
         recs = self.db.find_records(query)
         self.assertEquals(len(recs), 0)
-            
+
+
 class TestSQLiteBackend(TestDictBackend):
+
+    @dec.skip_without('sqlite3')
     def create_db(self):
         return SQLiteDB(location=tempfile.gettempdir())
     
diff --git a/IPython/testing/iptest.py b/IPython/testing/iptest.py
index e97ad63..1ce0c37 100644
--- a/IPython/testing/iptest.py
+++ b/IPython/testing/iptest.py
@@ -128,6 +128,7 @@ have['pymongo'] = test_for('pymongo')
 have['wx'] = test_for('wx')
 have['wx.aui'] = test_for('wx.aui')
 have['qt'] = test_for('IPython.external.qt')
+have['sqlite3'] = test_for('sqlite3')
 
 have['tornado'] = test_for('tornado.version_info', (2,1,0), callback=None)
 
@@ -204,7 +205,9 @@ def make_exclude():
                   ipjoin('config', 'default'),
                   ipjoin('config', 'profile'),
                   ]
-
+    if not have['sqlite3']:
+        exclusions.append(ipjoin('core', 'tests', 'test_history'))
+        exclusions.append(ipjoin('core', 'history'))
     if not have['wx']:
         exclusions.append(ipjoin('lib', 'inputhookwx'))