Python-根据日期过滤SQL查询

时间:2018-09-12 13:08:21

标签: python sql python-3.x pandas psycopg2

我正在尝试构建一个将根据系统日期进行过滤的SQL查询(查询最近7天完成的所有销售):

import React, {Fragment} from 'react';
import gql from 'graphql-tag';
import { withApollo } from 'react-apollo';
...

const getPosts =  gql`
{
    posts {
    _id
    title
    description
    user {
        _id
    }
  }
}`;


const deletePost = gql`
    mutation deletePost($_id: String){
        deletePost(_id: $_id)
    }
`;

class PostList extends React.Component {
    static propTypes = {
        match: PropTypes.object.isRequired,
        history: PropTypes.object.isRequired,
    };
    state = {posts: null};

    componentDidMount() {
        this.props.client.query({
                query: getPosts,
            }).then(({ data }) => {
                this.setState({ posts: data.posts });
            });
    }

    deletePost = postId => {
        this.props.client
            .mutate({
                mutation: deletePost,
                variables: {
                    _id: postId
                },
            })
            .then(({ data }) => {

                alert('Post deleted!');
            });
    };


    render() {
        const {posts} = this.state;    
        if (!posts) {
            return <div>Loading....</div>
        }

        return (
            <div className="post">
                ...stuff...
            </div>
        )
    }
}

export default withApollo(PostList);

我遇到错误

import datetime
import pandas as pd
import psycopg2

con = p.connect(db_details)
cur = con.cursor()

df = pd.read_sql("""select store_name,count(*) from sales 
     where created_at between datetime.datetime.now() - (datetime.today() - timedelta(7))""",con=con)

4 个答案:

答案 0 :(得分:2)

您正在将Python语法混入SQL查询中。 SQL是由数据库而不是Python解析和执行的,并且数据库对datetime.datetime.now()datetime.date()timedelta()一无所知!您看到的特定错误是由于Python代码被解释为SQL而被解释为SQL datetime.datetime.now引用了now表中的datetimedatetime数据库是跨数据库引用,而psycopg2不支持涉及多个数据库的查询。

相反,使用 SQL参数将值从Python传递到数据库。在SQL中使用占位符以向数据库驱动程序显示值应放在的位置:

params = {
    # all rows after this timestamp, 7 days ago relative to 'now'
    'earliest': datetime.datetime.now() - datetime.timedelta(days=7),
    # if you must have a date *only* (no time component), use
    # 'earliest': datetime.date.today() - datetime.timedelta(days=7),
}
df = pd.read_sql("""
     select store_name,count(*) from sales 
     where created_at >= %(latest)s""", params=params, con=con)

这使用psycopg2 parameters documentation定义的占位符,其中%(latest)slatest字典中的params键。驱动程序直接支持datetime.datetime()个实例。

请注意,我还修复了您的 7天前表达式,BETWEEN替换了>=语法;没有第二个日期,您就不会查询两个日期之间的值,因此请使用>=将列限制为给定日期或之后的日期。

答案 1 :(得分:1)

datetime.datetime.now()不是正确的SQL语法,因此不能由read_sql()执行。我建议要么使用计算当前时间的正确SQL语法,要么为每个datetime.datetime.now()datetime.today() - timedelta(7)创建变量,然后将其替换为字符串。

编辑:不要遵循第二条建议。请参阅以下Martijn Pieters的评论。

答案 2 :(得分:0)

也许您应该删除SQL中的Python代码,在python中计算日期,然后使用strftime函数将其转换为字符串。

然后,您将可以在SQL查询中使用它们。

答案 3 :(得分:0)

实际上,您不一定需要Python中的任何参数或计算。只需使用相应的SQL语句即可,如下所示:

select store_name,count(*)
from sales 
where created_at >= now()::date - 7
group by store_name

编辑:我还添加了一个group by,我认为它不见了。