首先声明:本文是中文译文,原文请点我

偶然看到一份关于Django工程目录的文章,英文版版的,觉得写得不错。在此翻译下供读者参考


Django 工程目录结构

你已经配置好你的Heroku账户(译者注:Heroku是一个老牌的免费云空间),并且创建了第一个Heroku应用,让我们来讨论一个非常重要的话题(虽然经常被忽略):Django工程结构管理。


概述

多数Django工程非常混乱。不幸的是默认的Django工程布局并没有对此有任何帮助,它过于简单对工程的管理导致在处理大的工程时带来很多维护性问题。

本文将帮助让你的工程有个合理的布局。致力于:

  • 遵循最佳实践

  • 让你的工程尽可能地直观--你(作为开发者)可以立即认出代码每个部分的作用

  • 让你工程仍然保持规范随着你的工程中的应用越来越多。

  • 让你工程在不同环境下部署更加方便

  • 让其他程序员喜欢你的代码


具体步骤

这部分我将和你一起开始一个新的项目。过程中,你需要将你的项目目录结构调整为下面描述的布局。

本文描述了高维护性结构分明的Django项目布局的最佳实践。


基础- 缺省的Django项目

在深入之前,让我们创建一个新的Django项目(工程)

$django-admin.py startproject djanolicious
$cd djangolicious
$tree .
.
├── djangolicious
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

1个目录,5个文件

在根目录djangolicious下,可以得到:

  • 项目目录:djangolicious

  • manage.py脚本:用于管理Django站点


在项目目录djangolicious里包含:

  • settings.py: 包含项目的所有配置参数

  • urls.py: URL根配置

  • wsgi.py: 内置runserver命令的WSGI应用配置

  • __init__.py: 用来告诉python,当前目录是python模块


现在让我们来看下一个工程的基本架构,让我们来做些改进。


管理项目需求说明

首先我们在项目中新建一个文件:requirements.txt。每个Django项目都应该有一个顶级的requirements.txt文件来列出项目中所有使用到的python包。

Note:如果你对于requirements文件不太熟悉,你可以阅读Heroku指引 来通过pip管理python的需求关系。

requirement.txt中类似如下内容:

Django==1.6
psycopy2==2.4.5
South==0.7.3
gunicorn==0.14.1
nrerelic==1.2.0.246
django-cerlery==2.4.2

创建requirements文件是为了让其他开发者 拷贝你的项目代码后可以快速地根据此文件中内容安装好必须的python依赖包。这样他们可以方便地运行你的代码,而不必煞费苦心地猜测项目依赖包的版本。

现在你知道为什么我们需要这么做了,照做吧!


第一步--模块化

  在项目目录中创建一个顶级的requirement.txt是必须遵循的要求,而且这样可以保证可以方便地管理项目依赖关系

  这意味着:很有可能,项目的开发环境依赖关系不同于你的生产环境,所有你需要将你的开发和生产环境的依赖都放到requirement.txt中,但是这会使得管理起来比较困难。

  所以,最好是区分好不同环境的依赖和需求

  我们的做法如下(在项目djangolicious根目录下):

$ls
djangolicious manage.py
$touch requirements.txt
$mkdir requirements
$touch requirements/{common.txt,dev.txt,prod.txt,test.txt}
$tree.
.
|-- djangolicious
|   |-- __init__.py
|   |-- settings.py
|   |-- urls.py
|   |-- wsgi.py 
|-- manage.py
|-- requirements
|   |-- common.txt
|   |-- dev.txt
|   |-- prod.txt
|   |-- test.txt
|-- requirements.txt

2个目录,10个文件

  可以看出,我新建了一个顶级目录:requirements,包含一系列的需求说明文件,分别针对每个环境。

  如果你的应用只需要在开发环境下运行,那么只需要在一个dev.txt文件。如果你的应用需要开发、生产、测试、tom和rudy环境下运行--那么就分别为他们创建一个.txt文件

Note:common.txt内含各种环境下共享的需求说明。例如Django。所有环境下都需要Django,不管是开发环境还是生产环境,你都需要使用它。

  将各类需求文件分开的目的是,当作为程序员的我只需要在本地环境下运行项目,那么我只需要安装requirement/dev.txt中提到的软件包,而不需要安装其他的包(生产环境,staging,测试环境等等)

  但是为什么我这么关心哪些包是我必须安装的?为什么我不将他们全部安装?

  • 安装依赖包需要耗费很长时间,对于大型项目来说可能会耗费大块的时间(30分钟以上)。

  • 很多需求依赖于外部软件或者库文件按装到你的本地机器来完成编译。这么避免安装库文件可以节省时间还可以免去大量不必要的麻烦,比如要安装哪个版本的libxml2和libpq-dev。

  • 降低了初学者学习的门槛。如果的你项目组来了一个新的开发,尝试提交代码,对他来说安装很少的软件包就可以运行系统要比安装所有软件包要简单的多。

第二步--定义需求文件

  现在我们明白了为什么要模块化需求说明文件,下面了解下实践中需求说明文件的具体内容。

  下面我列出了4个从我实际项目中拿来的需求说明文件,我将详细的给予说明。

  首先,requirements/common.txt文件列出了所有基本的需求包,其中的么个软件包在任何环境都是必须的(不管是开发环境,测试环境还是生产环境等的):

# requirements/common.txt
Django==1.4
django-cache-machine==0.6
django-celery==2.5.5
django-dajaxice==0.2
django-guardian==1.0.4
django-kombu==0.9.4
django-pagination==1.0.7
django-sorting==0.1
django-tastypie==0.9.11
Fabric==1.4.1
lxml==2.3.4
pyst2==0.4
South==0.7.4
Sphinx==1.1.3

 下面的requirements/dev.txt文件包含了我的开发环境所需要包,其中的包只有是在开发环境下才会用到。

# requirements/dev.txt
-r common.txt
django-debug-toolbar==0.9.4

  在我的开发环境,我通常使用轻量级的SQLite3数据库(所以我不需要安装任何驱动程序),而且非常好用的包django-debug-toolbar可以允许我检查数据库查询和性能问题,等等。

  可能你会疑惑文件第一行的作用,'-r common.txt'告诉pip引入所有通用的依赖包附加到后面列举内容。

  这将允许我在命令行中直接运行pip intal -r requirements/dev.txt来安装开发环境需要的所有依赖包:

$ pip install -r requirements/dev.txt
Downloading/unpacking Django==1.4 (from -r requirements/common.txt (line 1))
  Downloading Django-1.4.tar.gz (7.6Mb): 7.6Mb downloaded
  Running setup.py egg_info for package Django

Downloading/unpacking django-cache-machine==0.6 (from -r requirements/common.txt (line 2))
  Downloading django-cache-machine-0.6.tar.gz
  Running setup.py egg_info for package django-cache-machine

... snipped for brevity ...

从上面的运行结果可以看出,非常好用!当我们使用pip安装requirements/dev.txt中包,它不仅成功安装了开发环境中需要的依赖包,同时也将common.txt中列举的包都安装好了!非常漂亮!


下面是一个简单的requirements/pord.txt需求说明文件。其中包含了所有生产环境的依赖包和基本的依赖包:

# requirements/prod.txt
-r common.txt
boto==2.1.1
cssmin==0.1.4
django-compressor==1.1.2
django-htmlmin==0.5.1
django-pylibmc-sasl==0.2.4
django-storages==1.1.3
gunicorn==0.14.1
newrelic==1.2.0.246
psycopg2==2.4.5
pylibmc==1.2.2
raven==1.3.5
slimit==0.6

最后,这是一个比较旧的requirements/test.txt文件,列出测试环境下的依赖包。这些包用于项目的单元测试环节。

# requirements/test.txt
-r common.txt
django-coverage==1.2.2
django-nose==0.1.3
mock==0.8.0
nosexcover==1.0.7
  • 当我需要在本地开发环境下运行我的代码,我就安装requirements/dev.txt中的依赖包

  • 当我在生产环境下运行我的代码,就安装requirements/prod.txt中的依赖包

  • 当我要针对我的代码做一些测试的时候,我就安装requirements/test.txt中的依赖包


重点在于将你的项目依赖文件按照以下原则来拆分:

  • 简单的

  • 高效的

  • 直观的


第三步--Heroku最佳实践

  现在,我们模块化了我们的需求说明文件。我敢说你一定疑惑:为什么在项目根目录下还有个requirement.txt的文件?

  原因如下:

  • 标准化要求存在requirements.txt文件

  • Heroku在你部署项目的时候会自动读取你根目录下下的requirements.txt文件,并且将这些需求包安装起来。


  Heroku会安装你在requirements.txt中定义的所有包,你可以有多种选择:

  • 让Heroku安装所有的依赖包:comon.txt,dev.txt,prod.txt等

  • 让Heroku只安装他需要的包


我们使用Heroku来部署我们的站点,所有最好是让Heroku只安装必须的包。

因为Heroku需要做的事情少了,这会让我们部署后的项目更加快速。

打开根目录下的requirements.txt文件然后输入以下内容:

#Install all of our production dependencies only.
-r requirements/prod.txt

这样Heroku就会安装我们的要求来安装需要的包。


分离应用和库文件

管理Django工程接下来的工作就是把你的应用从库中分离出来。

总所周知,每个Django工程包括一系列的应用。有些应用中包含模型和视图等等。还有些是辅助性的应用。

通常,这些辅助应用用于自定义templatetag,管理命令以及一些其他代码。请不要将这些放到别的应用里面。

幸运的没,有一种简单的方法来构建的Django项目:

  • 开发人员可以很容易地找到你的django应用

  • 开发人员可以很容易的找到你的django库文件

  • 不要在你工程目录下包含大量的自定义应用,不要让你的目录结果混乱,而很难找到你想要的东西



我都会在每个Django工程的主目录下创建两个目录:apps和libs用来各自存放应用和库文件。

再看我们的例子工程:djangolicious,我的做法如下:

$ mkdir djangolicious/apps
$ mkdir djangolicious/libs
$ touch djangolicious/apps/__init__.py
$ touch djangolicious/libs/__init__.py
$ tree .
.
├── djangolicious
│   ├── apps
│   │   └── __init__.py
│   ├── __init__.py
│   ├── libs
│   │   └── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── requirements
│   ├── common.txt
│   ├── dev.txt
│   ├── prod.txt
│   └── test.txt
└── requirements.txt

4个目录,12个文件

如上所示,我的djangolicious工程中包含了新的apps目录和libs目录。剩下的就是将Django应用和库移动到合适的位置。

在djangolicious的例子中,我创建了一些django应用和库,现在到时候将django应用移动到合适位置。

$ cd djangolicious/apps
$ django-admin.py startapp blog
$ django-admin.py startapp reader
$ django-admin.py startapp news
$ cd ../libs
$ django-admin.py startapp management
$ django-admin.py startapp display
$ cd ../..
$ tree .
.
├── djangolicious
│   ├── apps
│   │   ├── blog
│   │   │   ├── __init__.py
│   │   │   ├── models.py
│   │   │   ├── tests.py
│   │   │   └── views.py
│   │   ├── __init__.py
│   │   ├── news
│   │   │   ├── __init__.py
│   │   │   ├── models.py
│   │   │   ├── tests.py
│   │   │   └── views.py
│   │   └── reader
│   │       ├── __init__.py
│   │       ├── models.py
│   │       ├── tests.py
│   │       └── views.py
│   ├── __init__.py
│   ├── libs
│   │   ├── display
│   │   │   ├── __init__.py
│   │   │   ├── models.py
│   │   │   ├── tests.py
│   │   │   └── views.py
│   │   ├── __init__.py
│   │   └── management
│   │       ├── __init__.py
│   │       ├── models.py
│   │       ├── tests.py
│   │       └── views.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── requirements
│   ├── common.txt
│   ├── dev.txt
│   ├── prod.txt
│   └── test.txt
└── requirements.txt

9个目录,32个文件

现在我们的工程已经有了实际的架构!已经将django应用和库文件清晰地分开了。这样不仅很容易找到想要的应用或者库,而且目录结构也是非常的清晰。

移动应用和库文件后,还需要更新你的引入路径。如果你之前的是这么写的:

# blog/views.py
from djangolicious.news.models import Newspaper
from djangolicious.display.templatetags import top_stories

那么你需要改成:

# blog/views.py
from djangolicious.apps.news.models import Newspaper
from djangolicious.libs.display.templatetags import top_stories

尽管import语句变长了,我发现这对于我这个开发者来找到我所引入的需要修改的app、librarie是很有帮助的。

你还需要更新你的settings文件来包含新的应用的路径:

# settings.py
INSTALLED_APPS = (
    ...
    'djangolicious.apps.blog',
    'djangolicious.apps.news',
    'djangolicious.apps.reader',
    ...
)

构建一个完美的Django settings模块

构建完美的Django settings模块被认为是Django开发的“必杀技”。每个开发者都有着自己的想法,也可能会为此争论。

然而,很多人的做法真实非常错误的。

在此,我来展示了一种正确的方法来构建完美的Django settings模块,不管你工程的大小,需求以及其他因素。

我们所创建的settings模块:

  • 允许你方便地分离Django各种环境(开发,生产,测试等等)。

  • 允许你保持所有配置信息都在版本控制下。

  • 允许你通过环境变量将密码和其他证书从基本代码中分离出来。

  • 让你可以方便地修改配置。

第一步--模块化,模块化,模块化

就像我们在前面的章节中处理需求说明文件那样,配置信息也需要模块化!

首先,让我们处理掉讨厌的默认settings.py,取而代之的是创建一个更好的目录结构:

$ rm djangolicious/settings.py
$ mkdir djangolicious/settings
$ touch djangolicious/settings/{__init__.py,common.py,dev.py,prod.py,test.py}
$ tree .
.
├── djangolicious
│   ├── apps
│   │   ├── blog
│   │   │   ├── __init__.py
│   │   │   ├── models.py
│   │   │   ├── tests.py
│   │   │   └── views.py
│   │   ├── __init__.py
│   │   ├── news
│   │   │   ├── __init__.py
│   │   │   ├── models.py
│   │   │   ├── tests.py
│   │   │   └── views.py
│   │   └── reader
│   │       ├── __init__.py
│   │       ├── models.py
│   │       ├── tests.py
│   │       └── views.py
│   ├── __init__.py
│   ├── libs
│   │   ├── display
│   │   │   ├── __init__.py
│   │   │   ├── models.py
│   │   │   ├── tests.py
│   │   │   └── views.py
│   │   ├── __init__.py
│   │   └── management
│   │       ├── __init__.py
│   │       ├── models.py
│   │       ├── tests.py
│   │       └── views.py
│   ├── settings
│   │   ├── common.py
│   │   ├── dev.py
│   │   ├── __init__.py
│   │   ├── prod.py
│   │   └── test.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── requirements
│   ├── common.txt
│   ├── dev.txt
│   ├── prod.txt
│   └── test.txt
└── requirements.txt

和需求说明文件一样,settings模块也应该针对每个环境一个配置文件(dev.py,prod.py,test.py),和一个被各种环境共享的文件(common.py)。


资源

严格来说,管理Django工程发很需要技术。

然而我也还没有很多好的书籍或者资料可以推荐给你。

要想更好地维护和管理工程,就需要你创建很多项目,并且持续地改进你的代码



译者注:终于翻译完了,内容上基本没有问题,不会影响读者理解,只是用词确实不是太好,还望谅解

在使用Django自带User模块时会遇到默认字段不够用的情况,在Django1.5以前可采用两种方式进行扩展:1、采用Profile的方式来扩展,即添加一个类似profile的模型和user模型关联,使用User做权限控制,Profile来存储用户相关信息。2、修改源代码,添加User Model字段。

Django1.5版本后开始支持自定义User模型。并且推荐使用此种方式。Django1.6后已经不再支持Profile方式。

Django1.6具体做法如下:

1、首先我新建一个project:customeuser。目录结构如下:

customuser
----customuser
--------__init__.py
--------settings.py
--------usls.py
--------wsgi.py
----manage.py

2、新增一个app:account。新的目录结构如下:

customuser
----account
--------__init__.py
--------admin.py
--------models.py
--------tests.py
--------views.py
----customuser
--------__init__.py
--------settings.py
--------usls.py
--------wsgi.py
----manage.py

3、编写app:account下的models.py。内容如下:

# coding=utf-8
from django.db import models

# Create your models here.
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
class MyDept(models.Model):
    name = models.CharField (u'部门',max_length=30)
    updept = models.ForeignKey("self",verbose_name='上级部门',related_name='MyDept_updept',null=True,blank=True)
    def __unicode__(self):
        return self.name
    class Meta:
        verbose_name = '部门'
        verbose_name_plural='部门'

class MyUserManager(BaseUserManager):
    def create_user(self, email, username, password=None):
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            username = username,            
            email=self.normalize_email(email),
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, username,password):
        user = self.create_user(
            email=self.normalize_email(email),
            username = username,
            password=password,            
        )
        user.is_admin = True
        user.save(using=self._db)
        return user

class MyUser(AbstractBaseUser):
    username = models.CharField(u'用户名',max_length=40,unique=True)
    chinesename = models.CharField(u'中文名',max_length=40)
    email = models.EmailField(
        verbose_name='邮箱',
        max_length=255,
        unique=True,
    )
    phone = models.CharField(u"电话",max_length=13,blank=True,null=True) 
    dep = models.ForeignKey(MyDept,verbose_name=u'所属部门',related_name='MyUser_dep',null=True)     
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    objects = MyUserManager()

    
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']
    
    class Meta:
        verbose_name = '用户'
        verbose_name_plural='用户'
    
    def get_short_name(self):  #此函数必须,在默认admin页面展现的时候,会用到该函数
        return self.chinesename
    def get_username(self):
        return self.username
    
    
    def get_full_name(self):
        return self.chinesename


    # On Python 3: def __str__(self):  #如果你使用的是python3,请用def __str__(self)代替 def __unicode__(self)
    def __unicode__(self):
        return self.chinesename

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True

    @property
    def is_staff(self):
        "Is the user a member of staff?"
        # Simplest possible answer: All admins are staff
        return self.is_admin

4、修改admin.py:

# coding=utf-8
from django.contrib import admin

# Register your models here.
# coding=utf-8
# from django.contrib import admin
from django import forms
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from account.models import MyDept
from account.models import MyUser
# Register your models here.
class MyDeptAdmin(admin.ModelAdmin):
    list_display = ('id','name','updept')

class UserCreationForm(forms.ModelForm):
    """A form for creating new users. Includes all the required
    fields, plus a repeated passroleword."""
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)

    class Meta:
        model = MyUser
        fields = ('username','email', 'dep')

    def clean_password2(self):
        # Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords don't match")
        return password2

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user


class UserChangeForm(forms.ModelForm):
    """A form for updating users. Includes all the fields on
    the user, but replaces the password field with admin's
    password hash display field.
    """
    password = ReadOnlyPasswordHashField()

    class Meta:
        model = MyUser
        fields = ['username','chinesename','email', 'password', 'is_active', 'is_admin','dep']
    def clean_password(self):
        # Regardless of what the user provides, return the initial value.
        # This is done here, rather than on the field, because the
        # field does not have access to the initial value
        return self.initial["password"]


class MyUserAdmin(UserAdmin):
    # The forms to add and change user instances
    form = UserChangeForm
    add_form = UserCreationForm

    # The fields to be used in displaying the User model.
    # These override the definitions on the base UserAdmin
    # that reference specific fields on auth.User.
    list_display = ('username','chinesename','phone','email', 'is_admin','dep')    
    list_filter = ('username','email')
    filter_horizontal=()  #注意:如果user模型中没有manytomanyfiled 需要在admin中修改,一定要加上此句。不然django会自动将groups左右filter_horizontal的参数来供用户选择,而本例中在定义user模型是未定义groups,会导致报错。
    #另:filter_horizontal()作用是选择manytomanyfiled字段的值。
    fieldsets = (
        (None, {'fields': ('username','chinesename','phone','email', 'password','dep')}),
    )
    # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
    # overrides get_fieldsets to use this attribute when creating a user.
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('username','chinesename','phone','email', 'password1', 'password2','dep')}
        ),
    )
    search_fields = ('username',)
    ordering = ('username',)
    
admin.site.register(MyDept,MyDeptAdmin)
admin.site.register(MyUser, MyUserAdmin)
admin.site.unregister(Group)

5、设置项目使用上面新增的User模型,修改settings.py

安装app:

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'account',  #新增的app:account
)

设置使用新的user模型,在settings.py中新增:

AUTH_USER_MODEL = 'account.MyUser'

6、同步数据库:


7、通过runserver启动服务后访问admin:



一、目的

每天将数据库A中某些表的数据增量备份到数据库B中相应的表中

二、应用场景

做了个运维服务管理平台,其中有一部分是对公司各游戏下载次数的统计。因为部分游戏下载服务器是在外网(其余通过CDN提供下载),统计的方法是直接在游戏下载服务器上每天执行脚本分析下载日志,然后将各游戏每天的下载次数数据插入到外网的一个数据库。运维服务管理平台web服务端部署在内网。

发现问题:运维服务管理平台因为是使用外网的数据,导致访问速度比较慢

解决方案:运维服务管理平台使用内网数据库,将外网数据库中每天的游戏更新次数数据,每天增量插入到内网的数据库中。

三、具体步骤

1、编写python脚本,查询外网数据库中相应表中昨天的数据,然后插入到内网数据库中,代码如下

# coding=utf-8
"""
#Author: blackholll
#Email: blackholll@163.com
#Created: 2014-04-16
#Purpose: sync increment date between two datebases
#Tables: ywreport_gameupdate,ywreport_lobbylogintimes
"""
import MySQLdb
import datetime
todaydate = datetime.datetime.now()  #获取今天的日期
yesterdaydate = str((todaydate-datetime.timedelta(days=1)).date())  #获取昨天的日期

#连接数据库
try:
    connfrom = MySQLdb.connect(host='1.1.1.1',user='blackholll',passwd='123456',db='dbname',port=3306,charset='utf8')
    curfrom = connfrom.cursor()
    connto =   MySQLdb.connect(host='192.168.1.6',user='blackholll',passwd='123456',db='dbname2',port=3306,charset='utf8')
    curto = connto.cursor()
    
#for table ywreport_gameupdate

    sqls= "select *from ywreport_gameupdate where date='%s'"%yesterdaydate  #查询昨天的数据
    curfrom.execute("select *from ywreport_gameupdate where date='%s'"%yesterdaydate)
    rows = curfrom.fetchall()
    for row in rows:
        print row
        sqlstr = "insert into ywreport_gameupdate(id,gameid,date,plateform_id,subarea,server_id,updates,operations,uptype_id,areaid) values(%d,'%s','%s','%d','%d',%d,%d,'%s',%d,%d)"%(row[0],row[1],row[2],row[3],row[4],row[5],row[6],row[7],row[8],row[9])
        curto.execute(sqlstr)

#for table ywreport_lobbylogintimes

    curfrom.execute("select *from ywreport_lobbylogintimes where date='%s'"%yesterdaydate) #查询昨天的数据
    rows = curfrom.fetchall()
    for row in rows:
        
        sqlstr = "insert into ywreport_lobbylogintimes(id,server_id,date,lobbytype_id,logintimes) values(%d,%d,'%s',%d,%d)"%(row[0],row[1],row[2],row[3],row[4])
        print sqlstr
        curto.execute(sqlstr)
    
    
    #关闭数据库连接
    connfrom.close() 
    curfrom.close()
    connto.close()
    curto.close()
    
except MySQLdb.Error,e:
    print e

注:本脚本实现了将1.1.1.1上数据库中ywreport_gameupdate和ywreport_lobbylogintimes表中昨天的数据插入到192.168.1.6相应的表中,

表名可以不同,字段名也可以不同,只需要稍微改下代码就行了。 另:本脚本需要安装mysqldb模块,安装方法在此不作说明,读者可以百度


2、通过linux的contab或者windows的计划任务实现每天定时执行。



闲话不多说,直接上例子:

一、获取当前精确时间:2014-04-16 15:13:09.061000

import datetime
print datetime.datetime.now()
print datetime.datetime.today()


二、获取当前日期:2014-04-16

import datetime
print datetime.datetime.now().date()   #时间类型
print str(datetime.datetime.now().date())  #字符串类型
print datetime.datetime.now().strftime('%Y-%m-%d') #字符串类型


三、日期加减:如获取明天的日期

import datetime
print (datetime.datetime.now()+datetime.timedelta(days=1)).date()  #获取明天的日期
print (datetime.datetime.now()+datetime.timedelta(days=-1)).date()  #获取昨天的日期


四、当前星期几

import datetime
print datetime.datetime.now().weekday() #返回结果是2 ,及周三(2+1),星期从0开始到6。


五、字符串转时间格式

import time
times  = '20140416'
timetime = time.strptime(times,'%Y%m%d')
timetime = time.strptime(times,'%Y-%m-%d %H:%M:%S')
print type(timetime)   #将打印 <type 'time.struct_time'>


一、JSON简介(来源百度百科)

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它基于JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。初学者。

二、生成JSON

import json
a = {'userid':'10','username':'jack'}
b = json.dumps(a) #通过json.dumps()将字典格式化为json格式

注意:json格式化的内容,在python中识别为str格式

三、读取及处理JSON

import json
a = {'userid':'10','username':'jack'}
b = json.dumps(a) #通过json.dumps()将字典格式化为json格式
jsonData = json.loads(b)
print jsonData['userid']