Versuchen Sie, die Datenbank mit Peewee von ORM of Python (Version August 2019) zu betreiben.

Überblick

peewee ist ein ORM für Python. Sie können die folgenden Datenbanken betreiben. ・ SQLite ・ MySQL ・ Postgres ・ AWSP ・ Berkeley-Datenbank (nicht überprüft)

Weitere Informationen finden Sie im folgenden Dokument. https://peewee.readthedocs.org/en/latest/index.html

Änderungsprotokoll

2019.08.03 Geänderter Beispielcode Python2.7 → Python3.7 & Peewee 3.9.6

Umgebung

Windows10 Python 3.7.4(32bit) Peewee 3.9.6

Wie installiert man

pip install peewee

Einfaches Beispiel

Unten finden Sie ein einfaches Beispiel aus 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():
        #EINFÜGEN durch Erstellen eines Objekts und Speichern
        uncle_bob = Person(name='Bob', birthday=date(1960, 1, 15), is_relative=True)
        uncle_bob.save() # bob is now stored in the database

        #INSERT mit 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 ("Nimm alle-----------------")
        for person in Person.select():
            print(person.name, person.is_relative)

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

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

        print("Beispiel aktualisieren-----------------")
        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("Löschbeispiel-----------------")
        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()

Wenn Sie wie in diesem Beispiel peewee verwenden, können Sie die Datenbank betreiben, ohne eine SQL-Anweisung zu schreiben. Weitere Gruppierungen und Abfragen mit den Funktionen max und min finden Sie im Folgenden.

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

Bei Verwendung einer Funktion wie SUBSTR

Wenn Sie eine Funktion wie SUBSTR verwenden möchten, verwenden Sie SQL ().

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

In diesem Beispiel wird das erste Zeichen der Namensspalte von der SUBSTR-Funktion erfasst und ihr der Spaltenname a1 zugewiesen.

Bei Verwendung von MAX, um den Maximalwert zu erhalten

Geben Sie eine Funktion in fn.MAX an und verwenden Sie scalar (), um den Wert aus der Abfrage abzurufen.

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

Große Datenmengen erstellen

Wenn Sie viele Daten gleichzeitig erstellen möchten, verwenden Sie 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 ("Nimm alle-----------------")
    for person in Person.select():
        print (person.name, person.birthday, person.is_relative)

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

Verwendung von DISTINCT

DISTINCT wird wie folgt verwendet.

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

Die zu erstellende SQL lautet wie folgt.

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

Bedingungen dynamisch zusammenbauen

Im folgenden Beispiel wird die Abfrage basierend auf operation_company und Railway_line abgerufen.

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: #Geben Sie hier SQL aus
        ret.append(r.name)
    return ret

In diesem Beispiel werden abhängig von der Parameterspezifikationsmethode vier SQL-Typen erstellt.

name is_relative SQL erstellt
None None SELECT "t1"."id", "t1"."name", "t1"."birthday", "t1"."is_relative" FROM "person" AS "t1
Andere als keine None SELECT "t1"."id", "t1"."name", "t1"."birthday", "t1"."is_relative" FROM "person" AS "t1" WHERE ("t1"."name" = ?)
None Andere als keine SELECT "t1"."id", "t1"."name", "t1"."birthday", "t1"."is_relative" FROM "person" AS "t1" WHERE ("t1"."is_relative" = ?)
Andere als keine Andere als keine SELECT "t1"."id", "t1"."name", "t1"."birthday", "t1"."is_relative" FROM "person" AS "t1" WHERE (("t1"."name" = ?) AND ("t1"."is_relative" = ?))

Der Zeitpunkt, zu dem das erstellte SQL tatsächlich ausgegeben wird, ist auch der Zeitpunkt, zu dem es verwendet werden soll. Mit diesem Verhalten können Sie Abfragen mit komplexen Bedingungen dynamisch erstellen.

Über JOIN

JOIN, das verwendet werden kann

RIGHT und FULL JOIN sind in Peewee 2.4.5 nicht verfügbar. Es kann nur INNER JOIN oder LEFT OUTER JOIN verwendet werden.

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

Wenn Sie JOIN_FULL angeben, tritt eine Ausnahme auf.

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


### Beispiel für LEFT OUTER JOIN
 Der abgerufene Datensatz enthält den Namen der Tabelle, die verbunden werden soll. Es ist eine gute Idee, die dir-Funktion zu verwenden, um den Inhalt des Datensatzes zu erstellen.

```py
#Modell-
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='Blumengruppe')
        grp1.save()
        grp2 = Group(name='Bizarre Gruppe')
        grp2.save()

        #EINFÜGEN durch Erstellen eines Objekts und Speichern
        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 mit 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 ("Nimm alle-----------------")
        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("Inner Join Beispiel-----------------")
        query = (Pet
                 .select(Pet, Person)
                 .join(Person))
        for pet in query:
            print(pet.name, pet.owner.name)


        print("linkes äußeres Join-Beispiel-----------------")
        query = (Pet
                 .select(Pet, Person)
                 .join(Person, JOIN.LEFT_OUTER))
        for pet in query:
            print(pet.name, pet.owner)

        #print("rechtes äußeres Join-Beispiel-----------------")
        #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()


```

### Beim Verbinden mehrerer Tabellen
 Wenn Sie mehreren Tabellen beitreten, müssen Sie einen Schalter verwenden, um anzugeben, welche Tabelle verbunden werden soll.
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)

```
### Selbstbindung
 Erstellen Sie beim Self-Join ein Objekt mit einem Alias in Alias und verwenden Sie es

```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)
```

## Modell erstellen
 In diesem Abschnitt wird beschrieben, wie Sie ein Modell erstellen.
 Siehe unten für Details.
https://peewee.readthedocs.org/en/latest/peewee/models.html

### Spaltentyp
 Felder können durch Angabe von DateField und CharField in der Model-Klasse wie im vorherigen Beispiel festgelegt werden.
 Die Felder, die hier verwendet werden können, sind wie folgt.

 |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|

 Sie können den Standardwert und das Vorhandensein oder Fehlen einer Duplizierung durch den Parameter beim Erstellen des Felds angeben.
 Siehe unten für Details.

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

## Angabe des Primärschlüssels
 Die Methode zum Angeben des Primärschlüssels mit Peewee wird nachfolgend erläutert.

### Wenn Sie den Primärschlüssel nicht einstellen
 Wenn Sie den Primärschlüssel nicht angeben, erstellen Sie einen Primärschlüssel mit dem Namen id für die automatische Inkrementierung.


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

    class Meta:
        database = db
``` 


 SQLite-Datenbank erstellt

```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
```

### Wenn Sie ein bestimmtes Feld als Primärschlüssel angeben
 Durch Angabe von primary_key = True beim Erstellen eines Felds wird dieses Feld zum Primärschlüssel.

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

    class Meta:
        database = db
```


 SQLite-Datenbank erstellt

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

### Machen Sie mehrere Felder zum Primärschlüssel
 Mit CompositeKey können mehrere Felder als Primärschlüssel verwendet werden.


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

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

 SQLite-Datenbank erstellt

```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"))
```

## Index angeben
 Die Methode zur Angabe des Index mit Peewee wird nachfolgend erläutert.

### Indizieren Sie ein bestimmtes einzelnes Feld
 Wenn Sie ein Feld erstellen, können Sie es indizieren, indem Sie index = True setzen

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

    class Meta:
        database = db
```

 Index erstellt

```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")
```

### Kombinieren Sie die angegebenen Felder zum Indexieren
 Durch Angabe von Indizes in der Meta-Klasse können Sie Indizes erstellen, indem Sie mehrere Schlüssel kombinieren.

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

    class Meta:
        database = db
        indexes = (
            #Am Ende,Wird zu einem Fehler führen
            #Mehrere Spezifikationen sind möglich
            (('name', 'birthday'), False),
        )
```

 Index erstellt

```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")
```

### Erstellen Sie einen Index, der die Duplizierung verhindert
 Sie können einen Index erstellen, der die Duplizierung verhindert, indem Sie beim Erstellen des Felds unique = True angeben oder im zweiten Argument der Indizes der Meta-Klasse True angeben.

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

    class Meta:
        database = db
        indexes = (
            #Am Ende,Wird zu einem Fehler führen
            #Mehrere Spezifikationen sind möglich
            (('name', 'birthday'), True),
        )
```

 Index erstellt

```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")
```

### Über externe Schlüssel
 Sie können einen Fremdschlüssel mit ForeignKeyField () angeben.

 Sie können mit to_field etwas anderes als den Primärschlüssel angeben, aber dieser Schlüssel muss einer der Primärschlüssel sein oder eine eindeutige Einschränkung haben.

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

## So stellen Sie eine Verbindung zu verschiedenen Datenbanken her
 Sie können mit peewee verschiedene Datenbanken verwenden.
 Siehe unten für Details.
https://peewee.readthedocs.org/en/latest/peewee/database.html

### SQLite-Verbindungsbeispiel
 Sie können eine Verbindung herstellen, indem Sie Speicher oder Datei angeben.

```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)
```

### APSW-Verbindungsbeispiel
 Weitere Informationen zu APSW und zur Installation finden Sie weiter unten.

 ** Versuchen Sie es mit APSW, einer Python-Bibliothek, die SQLite ernst nehmen kann **
https://qiita.com/mima_ita/items/711f4324da14cbd7741c

 Sie können es unten installieren.

```
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
```

 Sie können eine Verbindung herstellen, indem Sie Speicher oder Datei angeben.

 Da Commit beim Beenden mit ausgeführt wird, wird das letzte Commit auskommentiert (andernfalls tritt ein Fehler auf).

```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 
 
```

### Beispiel für eine MySQL-Verbindung
 Sie können eine Verbindung herstellen, indem Sie die Datenbank, den Benutzer, das Kennwort, den Host und den Port angeben.

```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])
```

#### Wenn Sie einen Verbindungsfehler erhalten
 Wenn Sie die folgende Fehlermeldung erhalten, installieren Sie bitte den MySQL-Treiber.

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

 ** Installationsbeispiel: **
```
pip3 install mysqlclient
```

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

 Wenn Sie Windows verwenden und eine Fehlermeldung erhalten, siehe unten.
https://stackoverflow.com/questions/51294268/pip-install-mysqlclient-returns-fatal-error-c1083-cannot-open-file-mysql-h

 Laden Sie die whl-Datei entsprechend Ihrer Umgebung herunter und geben Sie die Datei mit pip install an.

### Postgres-Verbindungsbeispiel
 Sie können eine Verbindung herstellen, indem Sie die Datenbank, den Benutzer, das Kennwort, den Host und den Port angeben.

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

#Standardmäßig verwendet Peewee eine Funktion namens 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])
```
#### Im Falle eines Verbindungsfehlers

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

 Installieren Sie psycopg2

```
pip install psycopg2
```

### So stellen Sie eine Verbindung zu Spatia Lite SQL her
 Beschreibt die Verbindung zu Spatia Lite, einer Erweiterung von SQLite, die räumliche Informationen verarbeitet.
http://qiita.com/mima_ita/items/64f6c2b8bb47c4b5b391

 Verwenden Sie dazu die SqliteExtDatabase in playhouse.sqlite_ext wie folgt:

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

# mod_Fügen Sie den Ordner mit Spatialite zu Ihrem PFAD hinzu
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_Laden von Spatialit
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)


```

 Die Punkte sind wie folgt.
 Rufen Sie mod_spatialite.dll / so mit load_extension an.
 -Spatialite-Spalten wie POINT und POLYGON werden durch Erben der Field-Klasse definiert, und das im Code in db.field_overrides angegebene db_field ist dem DB-Typnamen zugeordnet.
 -Verwenden Sie räumlich spezifische Funktionen wie AsText mit R ()

 Wenn Sie auf die RTreeIndex-Tabelle zugreifen, wird der folgende Fehler angezeigt.

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

 Führen Sie in diesem Fall SQL direkt aus. (Ich konnte die APSW-Datenbank nicht verwenden.)

```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 + '%'))
```


### So wählen Sie zur Laufzeit ein Verbindungsziel aus
 Mit der herkömmlichen Methode ist es nicht möglich, das Verbindungsziel zur Laufzeit anzugeben.
 Daher können Sie später mit Proxy () eine Verbindung herstellen, die mit den Informationen in der Konfigurationsdatei übereinstimmt.

```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

#Sie können die tatsächliche Datenbank später angeben
db = SqliteDatabase(':memory:', autocommit=False)
database_proxy.initialize(db)

db.create_tables([Person, Pet])

```

### Lesen Sie Slaves und Verbindungspool
 Abhängig von der Datenbank können Sie Read Slaves angeben, um auf eine schreibgeschützte Datenbank zuzugreifen, oder Sie können einen Verbindungspool verwenden, um mehrere Verbindungen zu verarbeiten.

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


## Schemamigration
 Peewee unterstützt die Schemamigration.
 Im Gegensatz zu anderen Schema-Migrationstools verfügt es nicht über eine Versionskontrolle, bietet jedoch Hilfsfunktionen für die Migration.

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

db = SqliteDatabase('mig.sqlite')

##Erstellen der ursprünglichen Datenbank
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()

##Schemamigration
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'),
    )


```

 Weitere Informationen finden Sie im Folgenden.
https://peewee.readthedocs.org/en/latest/peewee/playhouse.html#migrate

## So erstellen Sie ein Objekt aus einer vorhandenen Datenbank
 Mit pwiz können Sie Objekte aus einer vorhandenen Datenbank erstellen.

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

 Durch Ausführen dieses Befehls wird das Objekt standardmäßig aus people.db ausgegeben.

 Ausgabebeispiel

```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'
```


## SQL-Protokollierung
 So protokollieren Sie die von peewee ausgegebene SQL:


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

 Dadurch wird jedes Mal, wenn Sie SQL mit peewee ausgeben, das folgende Protokoll an stderr ausgegeben.

```
('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)', [])
```

## Zusammenfassung
 Wie oben erwähnt, wurde bestätigt, dass verschiedene DB-Operationen von Python aus ausgeführt werden können, ohne SQL mithilfe von Peewee zu schreiben.


Recommended Posts

Versuchen Sie, die Datenbank mit Peewee von ORM of Python (Version August 2019) zu betreiben.
Versuchen Sie, die Kamera mit Pythons OpenCV zu verwenden
Versuchen Sie, Excel mit Python (Xlwings) zu betreiben.
Versuchen Sie, mit n die von Ihnen installierte Version von Node.js herunterzustufen
Versuchen Sie es mit dem Feed-Parser von Python.
Versuchen Sie es mit Pythons Tkinter
Versuchen Sie, eine Excel-Datei mit Python (Pandas / XlsxWriter) zu betreiben
Versuchen Sie, eine Excel-Datei mit Python (Pandas / XlsxWriter) zu betreiben
Versuchen Sie, eine multimodale Verteilung mithilfe des EM-Algorithmus zu modellieren
Versuchen Sie es mit der Twitter-API
Versuchen Sie es mit der Twitter-API
Versuchen Sie es mit der PeeringDB 2.0-API
Versuchen Sie, ein neues Bild mit dem trainierten StyleGAN2-Modell zu bearbeiten
Versuchen Sie, das Problem der Funktionsminimierung mithilfe der Partikelgruppenoptimierung zu lösen
Sabayon Linux Portage Profile von 17.0 bis 17.1 / Versuchen Sie, die neueste Version von Sabayon mithilfe der Installationsmedien von Daily Builds zu installieren
Versuchen Sie, Facebook mit Python zu betreiben
Versuchen Sie, Nagios mit pynag zu konfigurieren
So erhalten Sie die Python-Version
Versuchen Sie, das Thema Pelican vorzustellen
Versuchen Sie, Statistiken mit e-Stat abzurufen
Versuchen Sie es mit dem Python Cmd-Modul
Probieren Sie Cython in kürzester Zeit aus
Der schnellste Weg, EfficientNet auszuprobieren
Versuchen Sie, Pythons networkx mit AtCoder zu verwenden
Der einfachste Weg, PyQtGraph auszuprobieren
Ich möchte DB mit Djangos ORM von einer externen Anwendung aus betreiben
Versuchen Sie es mit Pythons Webframework Django (1) - Von der Installation bis zum Serverstart
Versuchen Sie, den Zustand der Straßenoberfläche mithilfe von Big Data des Straßenoberflächenmanagements zu ermitteln