Essayez de faire fonctionner la base de données en utilisant Peewee de ORM de Python (version août 2019)

Aperçu

peewee est un ORM pour Python. Vous pouvez utiliser les bases de données suivantes. ・ SQLite ・ MySQL ・ Postgres ・ AWSP ・ Base de données Berkeley (non vérifiée)

Veuillez vous référer au document suivant pour plus de détails. https://peewee.readthedocs.org/en/latest/index.html

Journal des modifications

2019.08.03 Exemple de code modifié Python2.7 → Python3.7 & Peewee 3.9.6

environnement

Windows10 Python 3.7.4(32bit) Peewee 3.9.6

Comment installer

pip install peewee

Exemple simple

Voici un exemple simple de SQLite.

from peewee import *
from datetime import date

db = SqliteDatabase(':memory:')

class Person(Model):
    name = CharField()
    birthday = DateField()
    is_relative = BooleanField()

    class Meta:
        database = db # This model uses the "people.db" database.


class Pet(Model):
    owner = ForeignKeyField(Person, related_name='pets')
    name = CharField()
    animal_type = CharField()

    class Meta:
        database = db # this model uses the people database



try:
    db.create_tables([Person, Pet])
    with db.transaction():
        #INSÉRER en créant un objet et en enregistrant
        uncle_bob = Person(name='Bob', birthday=date(1960, 1, 15), is_relative=True)
        uncle_bob.save() # bob is now stored in the database

        #INSERT avec create
        grandma = Person.create(name='Grandma', birthday=date(1935, 3, 1), is_relative=True)
        herb = Person.create(name='Herb', birthday=date(1950, 5, 5), is_relative=False)

        bob_kitty = Pet.create(owner=uncle_bob, name='Kitty', animal_type='cat')
        herb_fido = Pet.create(owner=herb, name='Fido', animal_type='dog')
        herb_mittens = Pet.create(owner=herb, name='Mittens', animal_type='cat')
        herb_mittens_jr = Pet.create(owner=herb, name='Mittens Jr', animal_type='cat')

        print ("Avoir tout-----------------")
        for person in Person.select():
            print(person.name, person.is_relative)

        print("Obtenez seulement un chat-----------------")
        query = Pet.select().where(Pet.animal_type == 'cat')
        for pet in query:
            print(pet.name, pet.owner.name)

        print("Exemple de jointure-----------------")
        query = (Pet
                 .select(Pet, Person)
                 .join(Person)
                 .where(Pet.animal_type == 'cat'))
        for pet in query:
            print(pet.name, pet.owner.name)

        print("Exemple de mise à jour-----------------")
        update_pet = Pet.get(Pet.name=='Kitty')
        update_pet.name = 'Kitty(updated)'
        update_pet.save() 

        query = (Pet
                 .select(Pet, Person)
                 .join(Person)
                 .where(Pet.animal_type == 'cat'))
        for pet in query:
            print(pet.name, pet.owner.name)


        print("Exemple de suppression-----------------")
        del_pet = Pet.get(Pet.name=='Mittens Jr')
        del_pet.delete_instance() 

        query = (Pet
                 .select(Pet, Person)
                 .join(Person)
                 .where(Pet.animal_type == 'cat'))
        for pet in query:
            print(pet.name, pet.owner.name)

        db.commit()


except IntegrityError as ex:
    print (ex)
    db.rollback()

Si vous utilisez peewee comme dans cet exemple, vous pouvez utiliser la base de données sans écrire une instruction SQL. Pour d'autres regroupements et requêtes utilisant les fonctions max et min, reportez-vous à ce qui suit.

https://peewee.readthedocs.org/en/latest/peewee/querying.html

Lors de l'utilisation d'une fonction telle que SUBSTR

Si vous souhaitez utiliser une fonction telle que SUBSTR, utilisez SQL ().

        print ('Exemple SUBSTR')
        for r in Pet.select(SQL('SUBSTR(name,1,1)').alias('a1')):
            print (r.a1)

Dans cet exemple, le premier caractère de la colonne de nom est acquis par la fonction SUBSTR et le nom de colonne a1 lui est attribué.

Lorsque vous utilisez MAX pour obtenir la valeur maximale

Spécifiez une fonction dans fn.MAX et utilisez scalar () pour obtenir la valeur de la requête.

max = LiveChatMessage.select(
    fn.MAX(LiveChatMessage.offset_time_msec)
).where(LiveChatMessage.video_id  == video_id).scalar()
print(max)

Créer de grandes quantités de données

Si vous souhaitez créer un grand nombre de données à la fois, utilisez insert_many.

from peewee import *
from datetime import date

db = SqliteDatabase(':memory:')

class Person(Model):
    name = CharField()
    birthday = DateField()
    is_relative = BooleanField()

    class Meta:
        database = db

data_source = [
    {'name' : 'test1' , 'birthday' : date(1960, 1, 15), 'is_relative' : True},
    {'name' : 'test2' , 'birthday' : date(1960, 2, 15), 'is_relative' : True},
    {'name' : 'test3' , 'birthday' : date(1960, 3, 15), 'is_relative' : True},
    {'name' : 'test4' , 'birthday' : date(1960, 4, 15), 'is_relative' : True},
    {'name' : 'test5' , 'birthday' : date(1960, 5, 15), 'is_relative' : True},
]

db.create_tables([Person])
try:
    with db.transaction():
        Person.insert_many(data_source).execute()

    print ("Avoir tout-----------------")
    for person in Person.select():
        print (person.name, person.birthday, person.is_relative)

except IntegrityError as ex:
    print (ex)
    db.rollback()

Comment utiliser DISTINCT

DISTINCT s'utilise comme suit.

    q = Person.select(Person.name).distinct()
    print (q.sql())
    for person in q:
        print (person.name, person.birthday, person.is_relative)

Le SQL à créer est le suivant.

'('SELECT DISTINCT "t1"."name" FROM "person" AS "t1"', [])

Assemblez dynamiquement les conditions

Dans l'exemple ci-dessous, la requête est obtenue en fonction de operation_company et railway_line.

def get_dynamic_sql(name = None, is_relative = None):
    ret = []
    query = Person.select()
    cond = None
    if not name is None:
        cond = (Person.name == name)
    if not is_relative is None:
        if cond:
            cond = cond & (Person.is_relative == is_relative)
        else:
            cond = (Person.is_relative == is_relative)
    rows = query.where(cond)
    for r in rows: #Émettez SQL ici
        ret.append(r.name)
    return ret

Dans cet exemple, quatre types de SQL sont créés en fonction de la méthode de spécification des paramètres.

name is_relative SQL créé
None None SELECT "t1"."id", "t1"."name", "t1"."birthday", "t1"."is_relative" FROM "person" AS "t1
Autre que Aucun None SELECT "t1"."id", "t1"."name", "t1"."birthday", "t1"."is_relative" FROM "person" AS "t1" WHERE ("t1"."name" = ?)
None Autre que Aucun SELECT "t1"."id", "t1"."name", "t1"."birthday", "t1"."is_relative" FROM "person" AS "t1" WHERE ("t1"."is_relative" = ?)
Autre que Aucun Autre que Aucun SELECT "t1"."id", "t1"."name", "t1"."birthday", "t1"."is_relative" FROM "person" AS "t1" WHERE (("t1"."name" = ?) AND ("t1"."is_relative" = ?))

En outre, le moment où le SQL créé est réellement émis est celui de son utilisation. En utilisant ce comportement, vous pouvez créer dynamiquement des requêtes avec des conditions complexes.

À propos de JOIN

JOIN qui peut être utilisé

RIGHT et FULL JOIN ne sont pas disponibles dans peewee 2.4.5. Seules INNER JOIN ou LEFT OUTER JOIN peuvent être utilisées.

query = Curve.select(Curve, RailRoadSection).join(RailRoadSection, JOIN_FULL)

Si vous spécifiez JOIN_FULL, une exception se produira.

peewee.OperationalError: RIGHT and FULL OUTER JOINs are not currently supported
```


### Exemple LEFT OUTER JOIN
 L'enregistrement récupéré porte le nom de la table jointe. C'est une bonne idée d'utiliser la fonction dir pour faire le contenu de l'enregistrement.

```py
#modèle
from peewee import *
from datetime import date

db = SqliteDatabase(':memory:')

class Group(Model):
    name = CharField()

    class Meta:
        database = db # This model uses the "people.db" database.


class Person(Model):
    name = CharField()
    birthday = DateField()
    is_relative = BooleanField()
    group = ForeignKeyField(Group, related_name='group')

    class Meta:
        database = db # This model uses the "people.db" database.


class Pet(Model):
    owner = ForeignKeyField(Person, related_name='pets', null=True)
    name = CharField()
    animal_type = CharField()

    class Meta:
        database = db # this model uses the people database




try:
    db.create_tables([Person, Pet, Group])
    with db.transaction():
        # 
        grp1 = Group(name='Groupe de fleurs')
        grp1.save()
        grp2 = Group(name='Groupe bizarre')
        grp2.save()

        #INSÉRER en créant un objet et en enregistrant
        uncle_bob = Person(name='Bob', birthday=date(1960, 1, 15), is_relative=True, group=grp1)
        uncle_bob.save() # bob is now stored in the database

        #INSERT avec create
        grandma = Person.create(name='Grandma', birthday=date(1935, 3, 1), is_relative=True, group=grp2)
        herb = Person.create(name='Herb', birthday=date(1950, 5, 5), is_relative=False, group=grp1)

        bob_kitty = Pet.create(owner=herb, name='Kitty', animal_type='cat')
        herb_fido = Pet.create(owner=herb, name='Fido', animal_type='dog')
        herb_mittens = Pet.create(owner=herb, name='Mittens', animal_type='cat')
        herb_mittens_jr = Pet.create(owner=herb, name='Mittens Jr', animal_type='cat')
        ginga = Pet.create(owner=None, name='Mittens Jr', animal_type='cat')


        print ("Avoir tout-----------------")
        for group in Group.select():
            print(group.name)
        for person in Person.select():
            print(person.name, person.is_relative, person.group)
        for pet in Pet.select():
            print(pet.owner, pet.name, pet.animal_type)


        print("Exemple de jointure interne-----------------")
        query = (Pet
                 .select(Pet, Person)
                 .join(Person))
        for pet in query:
            print(pet.name, pet.owner.name)


        print("Exemple de jointure externe gauche-----------------")
        query = (Pet
                 .select(Pet, Person)
                 .join(Person, JOIN.LEFT_OUTER))
        for pet in query:
            print(pet.name, pet.owner)

        #print("Exemple de jointure externe droite-----------------")
        #query = (Pet
        #         .select(Pet, Person)
        #         .join(Person, JOIN.FULL))
        #for pet in query:
        #    print(pet.name, pet.owner)

except IntegrityError as ex:
    print (ex)
    db.rollback()


```

### Lors de la jointure de plusieurs tables
 Si vous souhaitez joindre plusieurs tables, vous devez utiliser un commutateur pour spécifier la table à joindre.
http://stackoverflow.com/questions/22016778/python-peewee-joins-multiple-tables

```py
#http://stackoverflow.com/questions/22016778/python-peewee-joins-multiple-tables
query = (TimeTableItem
    .select(TimeTableItem, TimeTable, BusStop)
    .join(TimeTable, on = (TimeTableItem.timeTable << list(timetableids.keys())))
    .switch(TimeTableItem)
    .join(BusStop, on=(TimeTableItem.busStop == BusStop.id))
)
for r in query:
    print (r.busStop.stopName)

```
### Auto-collage
 Lorsque vous effectuez une auto-jointure, créez un objet avec un alias dans l'alias et utilisez-le

```py
    fromBusStop = BusStopOrder.alias()
    toBusStop = BusStopOrder.alias()
    query = (fromBusStop
        .select(fromBusStop, toBusStop, BusStop)
        .join(
            toBusStop,
            on=((toBusStop.route == fromBusStop.route) & (toBusStop.stopOrder > fromBusStop.stopOrder))
            .alias('toBusStopOrder')
        )
        .switch(toBusStop)
        .join(BusStop, on=(toBusStop.busStop==BusStop.id))
        .where((fromBusStop.busStop==from_bus_stop))
    )
    for r in query:
        print (r.toBusStopOrder.busStop.id)
```

## Créer un modèle
 Cette section décrit comment créer un modèle.
 Voir ci-dessous pour plus de détails.
https://peewee.readthedocs.org/en/latest/peewee/models.html

### Type de colonne
 Les champs peuvent être définis en spécifiant DateField et CharField dans la classe Model comme dans l'exemple précédent.
 Les champs qui peuvent être utilisés ici sont les suivants.

 |Field Type |Sqlite |Postgresql |MySQL|
 |:---------:|:-----:|:---------:|:---:|
 |CharField |varchar |varchar |varchar|
 |TextField |text |text |longtext|
 |DateTimeField |datetime |timestamp |datetime|
 |IntegerField |integer |integer |integer|
 |BooleanField |smallint |boolean |bool|
 |FloatField |real |real |real|
 |DoubleField |real |double precision |double precision|
 |BigIntegerField |integer |bigint |bigint|
 |DecimalField |decimal |numeric |numeric|
 |PrimaryKeyField |integer |serial |integer|
 |ForeignKeyField |integer |integer |integer|
 |DateField |date |date |date|
 |TimeField |time |time |time|
 |BlobField |blob |bytea |blob|
 |UUIDField |not supported |uuid |not supported|

 Vous pouvez spécifier la valeur par défaut et la présence ou l'absence de duplication par le paramètre lors de la création du champ.
 Voir ci-dessous pour plus de détails.

https://peewee.readthedocs.org/en/latest/peewee/api.html#fields

## Spécifier la clé primaire
 La méthode de spécification de la clé primaire avec peewee est expliquée ci-dessous.

### Lorsque vous ne définissez pas la clé primaire
 Si vous ne spécifiez pas la clé primaire, créez une clé primaire appelée id pour l'incrémentation automatique.


```py
class Test1(Model):
    name = CharField()
    birthday = DateField()
    is_relative = BooleanField()

    class Meta:
        database = db
``` 


 Base de données SQLite créée

```sql
CREATE TABLE IF NOT EXISTS "test1" ("id" INTEGER NOT NULL PRIMARY KEY, "name" VARCHAR(255) NOT NULL, "birthday" DATE NOT NULL, "is_relative" INTEGER NOT NULL
```

### Lors de la spécification d'un champ spécifique comme clé primaire
 En spécifiant primary_key = True lors de la création d'un champ, ce champ sera la clé primaire.

```py
class Test2(Model):
    name = CharField(primary_key=True)
    birthday = DateField()
    is_relative = BooleanField()

    class Meta:
        database = db
```


 Base de données SQLite créée

```sql
CREATE TABLE IF NOT EXISTS "test2" ("name" VARCHAR(255) NOT NULL PRIMARY KEY, "birthday" DATE NOT NULL, "is_relative" INTEGER NOT NULL)
```

### Faire de plusieurs champs la clé primaire
 Plusieurs champs peuvent être utilisés comme clé primaire à l'aide de CompositeKey.


```py
class Test3(Model):
    name = CharField()
    birthday = DateField()
    is_relative = BooleanField()

    class Meta:
        database = db
        primary_key = CompositeKey('name', 'birthday')
```

 Base de données SQLite créée

```sql
CREATE TABLE IF NOT EXISTS "test3" ("name" VARCHAR(255) NOT NULL, "birthday" DATE NOT NULL, "is_relative" INTEGER NOT NULL, PRIMARY KEY ("name", "birthday"))
```

## Spécifier l'index
 La méthode de spécification de l'index avec peewee est expliquée ci-dessous.

### Indexer un champ unique spécifié
 Lors de la création d'un champ, vous pouvez l'indexer en définissant index = True

```py
class Test4(Model):
    name = CharField(index=True)
    birthday = DateField()
    is_relative = BooleanField()

    class Meta:
        database = db
```

 Index créé

```sql
CREATE TABLE IF NOT EXISTS "test4" ("id" INTEGER NOT NULL PRIMARY KEY, "name" VARCHAR(255) NOT NULL, "birthday" DATE NOT NULL, "is_relative" INTEGER NOT NULL)
CREATE INDEX IF NOT EXISTS "test4_name" ON "test4" ("name")
```

### Combiner les champs spécifiés pour indexer
 En spécifiant des index dans la classe Meta, vous pouvez créer des index en combinant plusieurs clés.

```py
class Test5(Model):
    name = CharField()
    birthday = DateField()
    is_relative = BooleanField()

    class Meta:
        database = db
        indexes = (
            #À la fin,Entraînera une erreur
            #Plusieurs spécifications sont possibles
            (('name', 'birthday'), False),
        )
```

 Index créé

```sql
CREATE TABLE IF NOT EXISTS "test5" ("id" INTEGER NOT NULL PRIMARY KEY, "name" VARCHAR(255) NOT NULL, "birthday" DATE NOT NULL, "is_relative" INTEGER NOT NULL)

CREATE INDEX IF NOT EXISTS "test5_name_birthday" ON "test5" ("name", "birthday")
```

### Créer un index qui interdit la duplication
 Vous pouvez créer un index qui interdit la duplication en spécifiant unique = True lors de la création du champ, ou en spécifiant True dans le deuxième argument des index de la classe Meta.

```py
class Test6(Model):
    name = CharField()
    birthday = DateField()
    is_relative = BooleanField()

    class Meta:
        database = db
        indexes = (
            #À la fin,Entraînera une erreur
            #Plusieurs spécifications sont possibles
            (('name', 'birthday'), True),
        )
```

 Index créé

```sql
CREATE TABLE IF NOT EXISTS "test6" ("id" INTEGER NOT NULL PRIMARY KEY, "name" VARCHAR(255) NOT NULL, "birthday" DATE NOT NULL, "is_relative" INTEGER NOT NULL)
CREATE UNIQUE INDEX IF NOT EXISTS "test6_name_birthday" ON "test6" ("name", "birthday")
```

### À propos des clés externes
 Vous pouvez spécifier une clé étrangère à l'aide de ForeignKeyField ().

 Vous pouvez spécifier autre chose que la clé primaire avec to_field, mais cette clé doit être l'une des clés primaires ou avoir une contrainte unique.

http://peewee.readthedocs.org/en/latest/peewee/api.html#ForeignKeyField

## Comment se connecter à diverses bases de données
 Vous pouvez utiliser diverses bases de données avec peewee.
 Voir ci-dessous pour plus de détails.
https://peewee.readthedocs.org/en/latest/peewee/database.html

### Exemple de connexion SQLite
 Vous pouvez vous connecter en spécifiant la mémoire ou le fichier.

```py
from peewee import *
from datetime import date

db = SqliteDatabase(':memory:')

class Person(Model):
    name = CharField()
    birthday = DateField()
    is_relative = BooleanField()

    class Meta:
        database = db

class Pet(Model):
    owner = ForeignKeyField(Person, related_name='pets')
    name = CharField()
    animal_type = CharField()

    class Meta:
        database = db

db.create_tables([Person, Pet], True)
```

### Exemple de connexion APSW
 Voir ci-dessous pour plus d'informations sur APSW et comment l'installer.

 ** Essayez d'utiliser APSW, une bibliothèque Python que SQLite peut prendre au sérieux **
https://qiita.com/mima_ita/items/711f4324da14cbd7741c

 Vous pouvez l'installer ci-dessous.

```
pip install --user https://github.com/rogerbinns/apsw/releases/download/3.28.0-r1/apsw-3.28.0-r1.zip --global-option=fetch --global-option=--version --global-option=3.28.0 --global-option=--all --global-option=build --global-option=--enable-all-extensions
```

 Vous pouvez vous connecter en spécifiant la mémoire ou le fichier.

 De plus, comme Commit est exécuté lors de la sortie avec, le dernier commit est commenté (sinon une erreur se produira).

```py
from peewee import *
from datetime import date
from playhouse.apsw_ext import APSWDatabase
from playhouse.apsw_ext import DateField

db = APSWDatabase('apswdatabase.sqlite')

class Person(Model):
    name = CharField()
    birthday = DateField()
    is_relative = BooleanField()

    class Meta:
        database = db 

class Pet(Model):
    owner = ForeignKeyField(Person, related_name='pets')
    name = CharField()
    animal_type = CharField()

    class Meta:
        database = db 

db.create_tables([Person, Pet])

#db.set_autocommit(False)
with db.transaction():
    # birthday=date(1960, 1, 15) ...
    uncle_bob = Person(name='Bob', birthday=date(1960, 1, 15), is_relative=True)
    uncle_bob.save() # bob is now stored in the database

    grandma = Person.create(name='Grandma', birthday=date(1960, 1, 5), is_relative=True)
    herb = Person.create(name='Herb', birthday='1950-05-05', is_relative=False)

    bob_kitty = Pet.create(owner=uncle_bob, name='Kitty', animal_type='cat')
    herb_fido = Pet.create(owner=herb, name='Fido', animal_type='dog')
    herb_mittens = Pet.create(owner=herb, name='Mittens', animal_type='cat')
    herb_mittens_jr = Pet.create(owner=herb, name='Mittens Jr', animal_type='cat')

    herb_mittens.delete_instance() 
    print ("-----------------")
    for person in Person.select():
        print (person.name, person.is_relative)

    print ("-----------------")
    query = Pet.select().where(Pet.animal_type == 'cat')
    for pet in query:
        print (pet.name, pet.owner.name)

    print ("-----------------")
    query = (Pet
             .select(Pet, Person)
             .join(Person)
             .where(Pet.animal_type == 'cat'))
    for pet in query:
        print (pet.name, pet.owner.name)
    #db.commit() # Not required for APSWDatabase 
 
```

### Exemple de connexion MySQL
 Vous pouvez vous connecter en spécifiant la base de données, l'utilisateur, le mot de passe, l'hôte et le port.

```py
from peewee import *
from datetime import date



db = MySQLDatabase(
    database='testdb',
    user='test',
    password="test",
    host="192.168.80.131",
    port=3306)

class Person(Model):
    name = CharField()
    birthday = DateField()
    is_relative = BooleanField()

    class Meta:
        database = db # This model uses the "people.db" database.

class Pet(Model):
    owner = ForeignKeyField(Person, related_name='pets')
    name = CharField()
    animal_type = CharField()

    class Meta:
        database = db # this model uses the people database

db.create_tables([Person, Pet])
```

#### Si vous obtenez une erreur de connexion
 Si vous obtenez l'erreur suivante, veuillez installer le pilote mysql.

```
peewee.ImproperlyConfigured: MySQL driver not installed!
```

 ** Exemple d'installation: **
```
pip3 install mysqlclient
```

https://github.com/coleifer/peewee/issues/1569

 Si vous utilisez Windows et obtenez une erreur, voir ci-dessous.
https://stackoverflow.com/questions/51294268/pip-install-mysqlclient-returns-fatal-error-c1083-cannot-open-file-mysql-h

 Téléchargez le fichier whl en fonction de votre environnement et spécifiez le fichier avec pip install.

### Exemple de connexion Postgres
 Vous pouvez vous connecter en spécifiant la base de données, l'utilisateur, le mot de passe, l'hôte et le port.

```py
from peewee import *
from datetime import date
from playhouse.postgres_ext import PostgresqlExtDatabase

#Par défaut, peewee utilise une fonction appelée hstore.
db = PostgresqlExtDatabase(
    database='peewee_test',
    user='postgres',
    password="",
    host="192.168.80.131",
    port=5432,
    register_hstore=False)

class Person(Model):
    name = CharField()
    birthday = DateField()
    is_relative = BooleanField()

    class Meta:
        database = db # This model uses the "people.db" database.

class Pet(Model):
    owner = ForeignKeyField(Person, related_name='pets')
    name = CharField()
    animal_type = CharField()

    class Meta:
        database = db # this model uses the people database

db.create_tables([Person, Pet])
```
#### En cas d'erreur de connexion

```
 ERROR: Could not find a version that satisfies the requirement psqlclient (from versions: none)
ERROR: No matching distribution found for psqlclient
```

 Installez psycopg2

```
pip install psycopg2
```

### Comment se connecter à Spatia Lite SQL
 Décrit la connexion à Spatia Lite, qui est une extension de SQLite qui gère les informations spatiales.
http://qiita.com/mima_ita/items/64f6c2b8bb47c4b5b391

 Pour ce faire, utilisez le SqliteExtDatabase dans playhouse.sqlite_ext comme suit:

```py
import os
from peewee import *
from playhouse.sqlite_ext import SqliteExtDatabase

# mod_Ajoutez le dossier avec spatialite à votre PATH
os.environ["PATH"] = os.environ["PATH"] + ';C:\\tool\\spatialite\\mod_spatialite-NG-win-x86'
db = SqliteExtDatabase('testspatialite.sqlite')

class PolygonField(Field):
    db_field = 'polygon'
db.field_overrides = {'polygon': 'POLYGON'}


# mod_Chargement spatialite
db.load_extension('mod_spatialite.dll')


class GeometryTable(Model):
  pk_uid  = PrimaryKeyField()
  n03_001 = CharField()
  n03_002 = CharField()
  n03_003 = CharField()
  n03_004 = CharField()
  n03_007 = CharField()
  Geometry = PolygonField()

  class Meta:
      database = db


for r in GeometryTable.select(GeometryTable.n03_001 ,  SQL('AsText(Geometry)').alias('Geo')).limit(10):
    print (r.n03_001, r.Geo)


```

 Les points sont les suivants.
 -Appeler mod_spatialite.dll / so en utilisant load_extension.
 -Les colonnes spatiales telles que POINT et POLYGON sont définies en héritant de la classe Field, et le db_field spécifié dans le code dans db.field_overrides est associé au nom du type de base de données.
 -Utiliser des fonctions spécifiques aux spatialites telles que AsText en utilisant R ()

 Si vous accédez à la table RTreeIndex, vous obtiendrez l'erreur suivante.

```
TypeError: 'idx_Station_geometry' object does not support indexing
```

 Dans ce cas, exécutez SQL directement. (Je n'ai pas pu utiliser la base de données APSW)

```py
    rows = database_proxy.connection().execute("""
        SELECT 
          statValue.value,
          AsGeoJson(MapArea.Geometry)
        FROM 
          MapArea 
          inner join idx_MapArea_Geometry ON pkid = MapArea.id AND xmin > ? AND ymin > ? AND xmax < ? AND ymax < ?
          inner join statValueAttr ON MapArea.stat_val_attr_id = statValueAttr.id 
          inner join statValueAttr AS b ON b.stat_value_id = statValueAttr.stat_value_id AND b.attr_value = ?
          inner join statValue ON statValue.id = b.stat_value_id
        WHERE 
          MapArea.stat_id like ?;
    """,(xmin, ymin, xmax, ymax, attr_value, stat_id_start_str + '%'))
```


### Comment sélectionner une destination de connexion au moment de l'exécution
 Avec la méthode conventionnelle, il n'est pas possible de spécifier la destination de la connexion lors de l'exécution.
 Par conséquent, vous pouvez utiliser Proxy () pour créer ultérieurement une connexion qui correspond aux informations du fichier de configuration.

```py
from peewee import *
from datetime import date

database_proxy = Proxy()  # Create a proxy for our db.


class Person(Model):
    name = CharField()
    birthday = DateField()
    is_relative = BooleanField()

    class Meta:
        database = database_proxy

class Pet(Model):
    owner = ForeignKeyField(Person, related_name='pets')
    name = CharField()
    animal_type = CharField()

    class Meta:
        database = database_proxy

#Vous pouvez spécifier la base de données réelle plus tard
db = SqliteDatabase(':memory:', autocommit=False)
database_proxy.initialize(db)

db.create_tables([Person, Pet])

```

### Lire les esclaves et le pool de connexions
 En fonction de la base de données, vous pouvez spécifier des esclaves en lecture pour accéder à une base de données en lecture seule ou vous pouvez utiliser un pool de connexions pour gérer plusieurs connexions.

https://peewee.readthedocs.org/en/latest/peewee/database.html#read-slaves
https://peewee.readthedocs.org/en/latest/peewee/database.html#connection-pooling


## Migration de schéma
 Peewee prend en charge la migration de schéma.
 Contrairement à d'autres outils de migration de schéma, il n'a pas de contrôle de version, mais il fournit des fonctions d'assistance pour la migration.

```py
from peewee import *
from datetime import date
from playhouse.migrate import *

db = SqliteDatabase('mig.sqlite')

##Création du DB d'origine
class Person(Model):
    name = CharField()
    birthday = DateField()
    is_relative = BooleanField()

    class Meta:
        database = db

db.create_tables([Person])
data_source = [
    {'name' : 'test1' , 'birthday' : date(1960, 1, 15), 'is_relative' : True},
    {'name' : 'test2' , 'birthday' : date(1960, 2, 15), 'is_relative' : True},
    {'name' : 'test3' , 'birthday' : date(1960, 3, 15), 'is_relative' : True},
    {'name' : 'test4' , 'birthday' : date(1960, 4, 15), 'is_relative' : True},
    {'name' : 'test5' , 'birthday' : date(1960, 5, 15), 'is_relative' : True},
    {'name' : 'test1' , 'birthday' : date(1960, 1, 15), 'is_relative' : True},
]
Person.insert_many(data_source).execute()

##Migration de schéma
migrator = SqliteMigrator(db)


title_field = CharField(default='')
status_field = IntegerField(null=True)

with db.transaction():
    migrate(
        migrator.add_column('Person', 'title', title_field),
        migrator.add_column('Person', 'status', status_field),
        migrator.drop_column('Person', 'is_relative'),
    )


```

 Veuillez vous référer à ce qui suit pour plus de détails.
https://peewee.readthedocs.org/en/latest/peewee/playhouse.html#migrate

## Comment créer un objet à partir d'une base de données existante
 Vous pouvez utiliser pwiz pour créer des objets à partir d'une base de données existante.

```
python -m pwiz --engine=sqlite mig.sqlite
```

 En exécutant cette commande, l'objet sera sorti en standard à partir de people.db.

 Exemple de sortie

```python
from peewee import *

database = SqliteDatabase('mig.sqlite')

class UnknownField(object):
    def __init__(self, *_, **__): pass

class BaseModel(Model):
    class Meta:
        database = database

class Person(BaseModel):
    birthday = DateField()
    name = CharField()
    status = IntegerField(null=True)
    title = CharField()

    class Meta:
        table_name = 'person'
```


## Journalisation SQL
 Pour enregistrer le SQL émis par peewee:


```py
import logging
logger = logging.getLogger('peewee')
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler())
```

 Cela affichera le journal suivant vers stderr chaque fois que vous émettez du code SQL avec peewee.

```
('SELECT name FROM sqlite_master WHERE type = ? ORDER BY name;', ('table',))
('CREATE TABLE "test1" ("id" INTEGER NOT NULL PRIMARY KEY, "name" VARCHAR(255) NOT NULL, "birthday" DATE NOT NULL, "is_relative" SMALLINT NOT NULL)', [])
```

## Résumé
 Comme mentionné ci-dessus, il a été confirmé que diverses opérations de base de données peuvent être effectuées à partir de Python sans écrire SQL en utilisant Peewee.


Recommended Posts

Essayez de faire fonctionner la base de données en utilisant Peewee de ORM de Python (version août 2019)
Essayez d'utiliser l'appareil photo avec OpenCV de Python
Essayez d'utiliser Excel en utilisant Python (Xlwings)
Essayez d'utiliser n pour rétrograder la version de Node.js que vous avez installée
Essayez d'utiliser l'analyseur de flux de Python.
Essayez d'utiliser Tkinter de Python
Essayez d'exploiter un fichier Excel en utilisant Python (Pandas / XlsxWriter) ①
Essayez d'exploiter un fichier Excel en utilisant Python (Pandas / XlsxWriter) ②
Essayez de modéliser une distribution multimodale à l'aide de l'algorithme EM
Essayez d'utiliser l'API Twitter
Essayez d'utiliser l'API Twitter
Essayez d'utiliser l'API PeeringDB 2.0
Essayez de modifier une nouvelle image à l'aide du modèle StyleGAN2 entraîné
Essayez de résoudre le problème de minimisation des fonctions en utilisant l'optimisation des groupes de particules
Sabayon Linux Portage Profile de 17.0 à 17.1 / Essayez d'installer la dernière version de Sabayon en utilisant le support d'installation Daily builds
Essayez d'exploiter Facebook avec Python
Essayez d'utiliser pynag pour configurer Nagios
Comment obtenir la version Python
Essayez d'introduire le thème sur Pelican
Essayez d'obtenir des statistiques en utilisant e-Stat
Essayez d'utiliser le module Python Cmd
Essayez Cython dans les plus brefs délais
Le moyen le plus rapide d'essayer EfficientNet
Essayez d'utiliser le networkx de Python avec AtCoder
La façon la plus simple d'essayer PyQtGraph
Je souhaite utiliser DB en utilisant l'ORM de Django à partir d'une application externe
Essayez d'utiliser le framework web de Python Django (1) - De l'installation au démarrage du serveur
Essayez d'obtenir l'état de la surface de la route en utilisant de grandes données de gestion de la surface de la route