sql >> Database teknologi >  >> RDS >> PostgreSQL

Python postgreSQL sqlalchemy forespørger en DATERANGE kolonne

Forespørgslen

the_daterange_lower = datetime.strptime(the_daterange[0], '%d.%m.%Y')
the_daterange_upper = datetime.strptime(the_daterange[1], '%d.%m.%Y')

bookings = UserBooks.query.\
    filter(UserBooks.booked_date.lower >= the_daterange_lower,
           UserBooks.booked_date.upper <= the_daterange_upper).\
    all()

kunne implementeres ved hjælp af "område er indeholdt af" operatoren <@ . For at bestå den rigtige operand skal du oprette en forekomst af >psycopg2.extras.DateRange , som repræsenterer et Postgresql daterange værdi i Python:

the_daterange_lower = datetime.strptime(the_daterange[0], '%d.%m.%Y').date()
the_daterange_upper = datetime.strptime(the_daterange[1], '%d.%m.%Y').date()

the_daterange = DateRange(the_dateranger_lower, the_daterange_upper)

bookings = UserBooks.query.\
    filter(UserBooks.booked_date.contained_by(the_daterange)).\
    all()

Bemærk, at attributterne lower og upper er en del af psycopg2.extras.Range typer. SQLAlchemy-områdekolonnetyperne giver ikke sådanne, som din fejl angiver.

Hvis du vil bruge rå SQL og pass datointervaller, kan du bruge det samme DateRange objekter for også at videregive værdier:

bookings = db_session.execute(
    'SELECT * FROM usersbookrooms WHERE booked_date && %s',
    (DateRange(the_daterange_lower, the_daterange_upper),))

Du kan også bygge bogstaver manuelt , hvis du vil:

bookings = db_session.execute(
    'SELECT * FROM usersbookrooms WHERE booked_date && %s::daterange',
    (f'[{the_daterange_lower}, {the_daterange_upper})',))

Tricket er at bygge det bogstavelige i Python og videregive det som en enkelt værdi - ved at bruge pladsholdere, som altid. Det bør undgå enhver SQL-injektionsmuligheder; det eneste, der kan ske, er, at bogstavet har ugyldig syntaks for et daterange . Alternativt kan du overføre grænserne til en områdekonstruktør :

bookings = db_session.execute(
    'SELECT * FROM usersbookrooms WHERE booked_date && daterange(%s, %s)',
    (the_daterange_lower, the_daterange_upper))

Alt i alt er det nemmere blot at bruge Psycopg2 Range typer og lad dem håndtere detaljerne.




  1. (Én tabel) få rækker ikke ind uden forening

  2. Forbedring af medianløsningen for rækkenummerering

  3. Sådan får du størrelsen på en tabel i MySQL

  4. table_exists()-metoden fungerer muligvis ikke korrekt