分类 python 下的文章

django重新整理migrations

在开发过程中,由于需求变更或者自我重构,需要清理migrations,以保持代码整洁和后续的可维护性。

场景一
不考虑数据库数据表,可以完全清空数据库里面的表的数据。
步骤:
删除所有migrations
find . -path "/migrations/.py" -not -name "init.py" -delete
find . -path "/migrations/.pyc" -delete
删除数据库的相关表
python manage.py makemigrations yourappname
python manage.py migrate yourappname

场景二
需要保留数据里面的数据,这种场景最为常见,只改结构不改数据
步骤:
使用migrate命令回滚0001_initial的migration history,回滚到最初
python manage.py migrate --fake yourappname zero

重新生成0001_initial,如果能保证已有0001_initial已是最新的,可跳过此步
find . -path "/migrations/.py" -not -name "init.py" -delete
find . -path "/migrations/.pyc" -delete

python manage.py makemigrations yourappname

在数据库中生成新的0001_initial记录
python migrate --fake-initial yourappname

另外,对于已经长期运行的项目,为了保留历史重大版本,不建议回到最初的版本,不利于版本控制。

如果中间有报错:
Django Table xxx already exist
python manage.py migrate --fake appname

参考:
https://segmentfault.com/a/1190000011594347

使用maxmind离线数据得到国家位置信息(python)

maxmind提供在线和离线的数据地理位置服务,http://dev.maxmind.com/geoip/,有收费的也有免费的,我这里的需求相对简单,只用根据IP得到国家即可,这里没有经过nginx,是后续扫描从一个存储好的日志里面根据IP得到国家的信息。

当然有很多实现的版本,这里讲如何利用python去实现,https://github.com/maxmind/GeoIP2-python

在虚拟环境里面按照geoip2,目前使用的python环境是2.6

pip install geoip2

下载免费的IP数据包,http://dev.maxmind.com/geoip/geoip2/geolite2/,我这里使用的是country级别的,有需要用到city粒度的可以使用city这个包,下载好后放到一个路径下面,程序里面会引用,简单的代码为:

import geoip2.database
reader = geoip2.database.Reader('/opt/GeoLite2-Country.mmdb')
response = reader.country('183.14.31.175')
print(response)

得到的结果为:

{
	'traits': {
		'ip_address': '183.14.31.175'
		},
	'country': {
		'geoname_id': 1814991,
		'iso_code': 'CN',
		'names': {
			'r': '\u041a\u0438\u0442\u0430\u0439', 
			'fr': 'Chine', 
			'en': 'China', 
			'de': 'China', 
			'zh-CN': '\u4e2d\u56fd', 
			'pt-BR': 'China', 
			'ja': '\u4e2d\u56fd', 
			'es': 'China'
			}
		}, 
	'continent': {
		'geoname_id': 6255147, 
		'code': 'AS', 
		'names': {
			'r': '\u0410\u0437\u0438\u044f', 
			'fr': 'Asie', 
			'en': 'Asia', 
			'de': 'Asien', 
			'zh-CN': '\u4e9a\u6d32', 
			'pt-BR': '\xc1sia', 
			'ja': '\u30a2\u30b8\u30a2', 
			'es': 'Asia'
			}
		}, 
	'registered_country': {
		'geoname_id': 1814991, 
		'iso_code': 'CN', 
		'names': {
			'r': '\u041a\u0438\u0442\u0430\u0439', 
			'fr': 'Chine', 
			'en': 'China', 
			'de': 'China', 
			'zh-CN': '\u4e2d\u56fd', 
			'pt-BR': 'China', 
			'ja': '\u4e2d\u56fd', 
			'es': 'China'
			}
		}
}

返回的结果里面废话挺多的,直接拿到country的iso_code即可。