python – 缓存地理编码数据的最简单方法
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – 缓存地理编码数据的最简单方法,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3996字,纯文字阅读大概需要6分钟。
内容图文
![python – 缓存地理编码数据的最简单方法](/upload/InfoBanner/zyjiaocheng/753/8577e187fe5943198fee8e789140403a.jpg)
我正在使用geopy来获取地址列表的lat / long坐标.所有文档都指向通过缓存限制服务器查询(事实上这里有许多问题),但很少有实际解决方案.
完成此任务的最佳方法是什么?
这是我正在处理的一个独立的数据处理工作…没有涉及的应用程序平台.只是尝试减少服务器查询,因为我运行的数据我以前会看到(很可能,在我的情况下).
我的代码看起来像这样:
from geopy import geocoders
def geocode( address ):
# address ~= "175 5th Avenue NYC"
g = geocoders.GoogleV3()
cache = addressCached( address )
if ( cache != False ):
# We have seen this exact address before,
# return the saved location
return cache
# Otherwise, get a new location from geocoder
location = g.geocode( address )
saveToCache( address, location )
return location
def addressCached( address ):
# What does this look like?
def saveToCache( address, location ):
# What does this look like?
解决方法:
您希望如何实现缓存实际上取决于您的Python代码将在哪个平台上运行.
你想要一个非常持久的“缓存”,因为地址的位置不会经常改变:-),所以数据库(在键值心情中)似乎是最好的.
所以在很多情况下我会选择sqlite3,这是一个优秀的,非常轻量级的SQL引擎,它是Python标准库的一部分.除非我更喜欢,例如我需要运行的MySQL实例,一个优点可能是这将允许在不同节点上运行的多个应用程序共享“缓存” – 其他数据库,无论是SQL还是非,都适合后者,取决于您的约束和偏好.
但是,如果我在谷歌应用引擎上运行,那么我将使用它包含的数据存储.除非我有特定的理由想要在多个不同的应用程序之间共享“缓存”,在这种情况下,我可能会考虑替代方案,如谷歌云sql和谷歌存储,以及另一种选择,包括专用的“缓存服务器”GAE应用程序我自己的服务RESTful结果(可能是端点?).选择是,再次!非常非常依赖于您的约束和偏好(延迟,每秒查询大小等等).
因此,请说明您所处的平台,以及您对数据库“缓存”的其他限制和偏好,然后可以轻松显示非常简单的实现代码.但在澄清之前显示六种不同的可能性并不会很有效.
补充:因为评论提示sqlite3可能是可以接受的,并且代码中最好显示了一些重要的细节(例如,如何将一个geopy.location.Location实例序列化和反序列化到sqlite3 blob中或从sqlite3 blob反序列化 – 类似的问题可能很好地与其他底层数据库一起出现,并且解决方案类似),我决定在代码中最好地展示解决方案示例.因此,由于“地理缓存”显然最好作为自己的模块实现,我编写了以下简单的geocache.py …:
import geopy
import pickle
import sqlite3
class Cache(object):
def __init__(self, fn='cache.db'):
self.conn = conn = sqlite3.connect(fn)
cur = conn.cursor()
cur.execute('CREATE TABLE IF NOT EXISTS '
'Geo ( '
'address STRING PRIMARY KEY, '
'location BLOB '
')')
conn.commit()
def address_cached(self, address):
cur = self.conn.cursor()
cur.execute('SELECT location FROM Geo WHERE address=?', (address,))
res = cur.fetchone()
if res is None: return False
return pickle.loads(res[0])
def save_to_cache(self, address, location):
cur = self.conn.cursor()
cur.execute('INSERT INTO Geo(address, location) VALUES(?, ?)',
(address, sqlite3.Binary(pickle.dumps(location, -1))))
self.conn.commit()
if __name__ == '__main__':
# run a small test in this case
import pprint
cache = Cache('test.db')
address = '1 Murphy St, Sunnyvale, CA'
location = cache.address_cached(address)
if location:
print('was cached: {}\n{}'.format(location, pprint.pformat(location.raw)))
else:
print('was not cached, looking up and caching now')
g = geopy.geocoders.GoogleV3()
location = g.geocode(address)
print('found as: {}\n{}'.format(location, pprint.pformat(location.raw)))
cache.save_to_cache(address, location)
print('... and now cached.')
我希望这里说明的想法足够清晰 – 每个设计选择都有其他选择,但我试图保持简单(特别是,当我运行此模块时,我正在使用一个简单的示例兼迷你测试直接,代替一套适当的单元测试…).
关于序列化到/从blob的位置,我选择了具有“最高协议”(-1)协议的pickle – cPickle当然在Python 2中也同样好(并且更快:-)但是这些天我尝试了编写与Python 2或3一样好的代码,除非我有特殊的理由不这样做:-).当然,我正在为测试中使用的sqlite数据库使用不同的文件名test.db,因此您可以毫无疑问地将其擦除以测试某些变体,而默认文件名意味着在“生产”代码中使用完整(使用相对的文件名 – 这意味着“在当前目录中”是一个非常可疑的设计选择 – 但是决定放置这样一个文件的适当方式是非常依赖平台的,我不想在这里进入这样的exoterica :-).
如果还有其他任何问题,请询问(也许最好在一个单独的新问题,因为这个答案已经变得如此之大! – ).
内容总结
以上是互联网集市为您收集整理的python – 缓存地理编码数据的最简单方法全部内容,希望文章能够帮你解决python – 缓存地理编码数据的最简单方法所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。