From 7f85c5ff21d0f95b23b0734324da5579fb4b1516 Mon Sep 17 00:00:00 2001 From: Stefan Wojcik Date: Thu, 19 Sep 2013 14:29:39 -0700 Subject: [PATCH 1/4] faster find_zip + optional exact queries + limit --- pyzipcode/__init__.py | 56 +++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/pyzipcode/__init__.py b/pyzipcode/__init__.py index da3b76b..757c729 100644 --- a/pyzipcode/__init__.py +++ b/pyzipcode/__init__.py @@ -10,12 +10,12 @@ class ConnectionManager(object): """ Assumes a database that will work with cursor objects """ - + def __init__(self): # test out the connection... conn = sqlite3.connect(db_location) conn.close() - + def query(self, sql, args): conn = None retry_count = 0 @@ -27,10 +27,10 @@ def query(self, sql, args): except sqlite3.OperationalError, x: retry_count += 1 time.sleep(0.001) - + if not conn and retry_count > 10: raise sqlite3.OperationalError("Can't connect to sqlite database.") - + cursor = conn.cursor() cursor.execute(sql, args) res = cursor.fetchall() @@ -39,7 +39,6 @@ def query(self, sql, args): ZIP_QUERY = "SELECT * FROM ZipCodes WHERE zip=?" ZIP_RANGE_QUERY = "SELECT * FROM ZipCodes WHERE longitude >= %s and longitude <= %s AND latitude >= %s and latitude <= %s" -ZIP_FIND_QUERY = "SELECT * FROM ZipCodes WHERE city LIKE ? AND state LIKE ?" class ZipCode(object): def __init__(self, data): @@ -59,56 +58,61 @@ def format_result(zips): class ZipNotFoundException(Exception): pass - + class ZipCodeDatabase(object): - + def __init__(self, conn_manager=None): if conn_manager is None: conn_manager = ConnectionManager() self.conn_manager = conn_manager - + def get_zipcodes_around_radius(self, zip, radius): zips = self.get(zip) if zips is None: raise ZipNotFoundException("Could not find zip code you're searching by.") else: zip = zips[0] - + radius = float(radius) - + long_range = (zip.longitude-(radius/69.0), zip.longitude+(radius/69.0)) lat_range = (zip.latitude-(radius/49.0), zip.latitude+(radius/49.0)) - + return format_result(self.conn_manager.query(ZIP_RANGE_QUERY % ( long_range[0], long_range[1], lat_range[0], lat_range[1] ))) - - def find_zip(self, city=None, state=None): + + def find_zip(self, city=None, state=None, limit=None, exact=False): + cmp = ' LIKE ' if not exact else '=' + if not city and not state: + q = "SELECT * FROM ZipCodes" + elif state and city: + q = "SELECT * FROM ZipCodes WHERE city%(cmp)s? AND state%(cmp)s?" % {'cmp': cmp} + if city is None: - city = "%" + q = "SELECT * FROM ZipCodes WHERE state%s?" % cmp else: city = city.upper() - + if state is None: - state = "%" + q = "SELECT * FROM ZipCodes WHERE city%s?" % cmp else: state = state.upper() - - return format_result(self.conn_manager.query(ZIP_FIND_QUERY, [city, state])) - + + if limit is not None: + q+= ' LIMIT 0, %d' % limit + + args = [arg for arg in [city, state] if arg] + return format_result(self.conn_manager.query(q, args)) + def get(self, zip): return format_result(self.conn_manager.query(ZIP_QUERY, [zip])) - + def __getitem__(self, zip): zip = self.get(str(zip)) if zip is None: raise IndexError("Couldn't find zip") else: return zip[0] - - - - - - + From d65fa6c89915d9a50dce494a763f6e09294ef308 Mon Sep 17 00:00:00 2001 From: Stefan Wojcik Date: Thu, 19 Sep 2013 18:07:57 -0700 Subject: [PATCH 2/4] fix find_zip with no args --- pyzipcode/__init__.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pyzipcode/__init__.py b/pyzipcode/__init__.py index 757c729..05a458d 100644 --- a/pyzipcode/__init__.py +++ b/pyzipcode/__init__.py @@ -89,16 +89,16 @@ def find_zip(self, city=None, state=None, limit=None, exact=False): q = "SELECT * FROM ZipCodes" elif state and city: q = "SELECT * FROM ZipCodes WHERE city%(cmp)s? AND state%(cmp)s?" % {'cmp': cmp} - - if city is None: - q = "SELECT * FROM ZipCodes WHERE state%s?" % cmp - else: - city = city.upper() - - if state is None: - q = "SELECT * FROM ZipCodes WHERE city%s?" % cmp else: - state = state.upper() + if city is None: + q = "SELECT * FROM ZipCodes WHERE state%s?" % cmp + else: + city = city.upper() + + if state is None: + q = "SELECT * FROM ZipCodes WHERE city%s?" % cmp + else: + state = state.upper() if limit is not None: q+= ' LIMIT 0, %d' % limit From cab7cc1d25da2b723d48b9e428b57204a2e8d3bf Mon Sep 17 00:00:00 2001 From: Stefan Wojcik Date: Mon, 7 Oct 2013 12:33:28 +0200 Subject: [PATCH 3/4] is None comparison --- pyzipcode/__init__.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pyzipcode/__init__.py b/pyzipcode/__init__.py index 05a458d..d8e0a02 100644 --- a/pyzipcode/__init__.py +++ b/pyzipcode/__init__.py @@ -3,7 +3,6 @@ import sqlite3 except ImportError: from pysqlite2 import dbapi2 as sqlite3 -import math import time class ConnectionManager(object): @@ -85,9 +84,9 @@ def get_zipcodes_around_radius(self, zip, radius): def find_zip(self, city=None, state=None, limit=None, exact=False): cmp = ' LIKE ' if not exact else '=' - if not city and not state: + if city is None and state is None: q = "SELECT * FROM ZipCodes" - elif state and city: + elif state is not None and city is not None: q = "SELECT * FROM ZipCodes WHERE city%(cmp)s? AND state%(cmp)s?" % {'cmp': cmp} else: if city is None: @@ -103,7 +102,7 @@ def find_zip(self, city=None, state=None, limit=None, exact=False): if limit is not None: q+= ' LIMIT 0, %d' % limit - args = [arg for arg in [city, state] if arg] + args = [arg for arg in [city, state] if arg is not None] return format_result(self.conn_manager.query(q, args)) def get(self, zip): From 8496afbed0f2e08f9e8ebc539f642892962a7084 Mon Sep 17 00:00:00 2001 From: Vyacheslav Tverskoy Date: Thu, 25 Apr 2019 21:09:27 +0500 Subject: [PATCH 4/4] Python 3 compatibility --- pyzipcode/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyzipcode/__init__.py b/pyzipcode/__init__.py index d8e0a02..9d0ff66 100644 --- a/pyzipcode/__init__.py +++ b/pyzipcode/__init__.py @@ -1,4 +1,4 @@ -from settings import db_location +from .settings import db_location try: import sqlite3 except ImportError: @@ -23,7 +23,7 @@ def query(self, sql, args): # then just give up... try: conn = sqlite3.connect(db_location) - except sqlite3.OperationalError, x: + except sqlite3.OperationalError: retry_count += 1 time.sleep(0.001)