2019年3月30日 星期六

[ Python 文章收集 ] SQLAlchemy ORM - Declaring Mapping & Creating Session (8)

Source From Here 
Preface 
The main objective of the Object Relational Mapper API of SQLAlchemy is to facilitate associating user-defined Python classes with database tables, and objects of those classes with rows in their corresponding tables. Changes in states of objects and rows are synchronously matched with each other. SQLAlchemy enables expressing database queries in terms of user defined classes and their defined relationships. 

The ORM is constructed on top of the SQL Expression Language. It is a high level and abstracted pattern of usage. In fact, ORM is an applied usage of the Expression Language

Although a successful application may be constructed using the Object Relational Mapper exclusively, sometimes an application constructed with the ORM may use the Expression Language directly where specific database interactions are required. 

Declaring Mapping 
First of all, create_engine() function is called to set up an Engine object which is subsequently used to perform SQL operations. The function has two arguments, one is the name of database and other is an echo parameter when set to True will generate the activity log. If it doesn’t exist, the database will be created: 
  1. from sqlalchemy import create_engine  
  2.   
  3. db_string = "postgresql://postgres:password@localhost/testdb"  
  4. engine = create_engine(db_string, echo = True)  
The Engine establishes a real DBAPI connection to the database when a method like Engine.execute() or Engine.connect() is called. It is then used to emit the SQLORM which does not use the Engine directly; instead, it is used behind the scenes by the ORM. 

In case of ORM, the configurational process starts by describing the database tables and then by defining classes which will be mapped to those tables. In SQLAlchemy, these two tasks are performed together. This is done by using Declarative system; the classes created include directives to describe the actual database table they are mapped to. 

A base class stores a catlog of classes and mapped tables in the Declarative system. This is called as the declarative base class. There will be usually just one instance of this base in a commonly imported module. The declarative_base() function is used to create base class. This function is defined in sqlalchemy.ext.declarative module: 
  1. from sqlalchemy.ext.declarative import declarative_base  
  2. Base = declarative_base()  
Once base classis declared, any number of mapped classes can be defined in terms of it. Following code defines a Customer’s class. It contains the table to be mapped to, and names and datatypes of columns in it: 
  1. class Customers(Base):  
  2.    __tablename__ = 'customers'  
  3.      
  4.    id = Column(Integer, primary_key = True)  
  5.    name = Column(String)  
  6.    address = Column(String)  
  7.    email = Column(String)  
A class in Declarative must have a __tablename__ attribute, and at least one Column which is part of a primary key. Declarative replaces all the Column objects with special Python accessors known as descriptors. This process is known as instrumentation which provides the means to refer to the table in a SQL context and enables persisting and loading the values of columns from the database. 

This mapped class like a normal Python class has attributes and methods as per the requirement. 

The information about class in Declarative system, is called as table metadata. SQLAlchemy uses Table object to represent this information for a specific table created by Declarative. The Table object is created according to the specifications, and is associated with the class by constructing a Mapper object. This mapper object is not directly used but is used internally as interface between mapped class and table. 

Each Table object is a member of larger collection known as MetaData and this object is available using the .metadata attribute of declarative base class. The MetaData.create_all() method is, passing in our Engine as a source of database connectivity. For all tables that haven’t been created yet, it issues CREATE TABLE statements to the database: 
  1. Base.metadata.create_all(engine)  
The complete script to create a database and a table, and to map Python class is given below: 
- demo00.py 
  1. from sqlalchemy import Column, Integer, String  
  2. from sqlalchemy import create_engine  
  3. from sqlalchemy.ext.declarative import declarative_base  
  4.   
  5. db_string = "postgresql://postgres:password@localhost/testdb"  
  6. engine = create_engine(db_string, echo = True)  
  7. Base = declarative_base()  
  8.   
  9. class Customers(Base):  
  10.    __tablename__ = 'customers'  
  11.    id = Column(Integer, primary_key=True)  
  12.    name = Column(String)  
  13.    address = Column(String)  
  14.    email = Column(String)  
  15.    Base.metadata.create_all(engine)  
When executed, Python console will echo following SQL expression being executed: 
  1. CREATE TABLE customers (  
  2.    id INTEGER NOT NULL,  
  3.    name VARCHAR,  
  4.    address VARCHAR,  
  5.    email VARCHAR,  
  6.    PRIMARY KEY (id)  
  7. )  
If you check the DB: 
  1. testdb=# \d+ customers  
  2.                                                    Table "public.customers"  
  3. Column  |       Type        |                       Modifiers                        | Storage  | Stats target | Description  
  4. ---------+-------------------+--------------------------------------------------------+----------+--------------+-------------  
  5. id      | integer           | not null default nextval('customers_id_seq'::regclass) | plain    |              |  
  6. name    | character varying |                                                        | extended |              |  
  7. address | character varying |                                                        | extended |              |  
  8. email   | character varying |                                                        | extended |              |  
  9. Indexes:  
  10.     "customers_pkey" PRIMARY KEY, btree (id)  
  11. Has OIDs: no  
Creating Session 
In order to interact with the database, we need to obtain its handle. A session object is the handle to databaseSession class is defined using sessionmaker() – a configurable session factory method which is bound to the engine object created earlier: 
  1. from sqlalchemy.orm.session import sessionmaker  
  2. session = sessionmaker(bind = engine)  
The session object is then set up using its default constructor. Some of the frequently required methods of session class are listed below: 
* begin(subtransactions=False, nested=False): Begin a transaction on this Session.
* add(instance, _warn=True): Add the given collection of instances to this Session.
* add_all(instances): Add the given collection of instances to this Session.
* commit(): Flush pending changes and commit the current transaction.
* delete(): Mark an instance as deleted.
* flush(): Flush all the object changes to the database.
* rollback(): Rollback the current transaction in progress.
* close(): Close this Session.


Supplement 
SQLAlchemy doc - Engine Configuration 
SQLAlchemy doc - Declarative API 
SQLAlchemy doc - Mapping Table Columns 
SQLAlchemy doc - Using the Session

[ Python 文章收集 ] wxPython - First steps in wxPython

Source from here 
Preface 
In this part of the wxPython tutorial, we will create some simple examples. 

Simple example 
We start with a very simple example. Our first script will only show a small window. It will not do much. We will analyse the script line by line. 
simply.py 
  1. #!/usr/bin/env python3  
  2. # -*- coding: utf-8 -*-  
  3.   
  4. # simple.py  
  5.   
  6. import wx  
  7.   
  8. app = wx.App()  # Create an application object.  
  9.   
  10. frame = wx.Frame(None, title='Simple application')  
  11. frame.Show()  
  12.   
  13. app.MainLoop()  


wx.Frame widget is an important container widget. We will analyse this widget in detail later. The wx.Frame widget is a parent widget for other widgets. It has no parent itself. If we specify None for a parent parameter we indicate that our widget has no parents. It is a top widget in the hierarchy of widgets. After we create the wx.Frame widget, we must call the Show() method to actually display it on the screen. 

The last line enters the mainloop. The mainloop is an endless cycle. It catches and dispatches all events that exist during the life of our application. 

This was a very simplistic example. Despite this simplicity we can do quite a lot with this window. We can resize the window, maximise it, minimise it. This functionality requires a lot of coding. All this is hidden and provided by default by the wxPython toolkit. There is no reason for reinventing the wheel. 

wx.Frame 
wx.Frame widget is one of the most important widgets in wxPython. It is a container widget. It means that it can contain other widgets. Actually it can contain any window that is not a frame or dialog. wx.Frame consists of a title bar, borders and a central container area. The title bar and borders are optional. They can be removed by various flags. 

wx.Frame has the following constructor: 
  1. Frame(parent, id=ID_ANY, title="", pos=DefaultPosition,  
  2.       size=DefaultSize, style=DEFAULT_FRAME_STYLE, name=FrameNameStr)  
wx.DEFAULT_FRAME_STYLE is a set of default flags: wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN. By combining various styles we can change the style of the wx.Frame widget. 
no_minimize.py 
  1. #!/usr/bin/env python3  
  2. # -*- coding: utf-8 -*-  
  3.   
  4. # no_minimize.py  
  5.   
  6. import wx  
  7.   
  8. app = wx.App()  
  9. frame = wx.Frame(None, style=wx.MAXIMIZE_BOX | wx.RESIZE_BORDER  
  10.     | wx.SYSTEM_MENU | wx.CAPTION |  wx.CLOSE_BOX)  
  11. frame.Show(True)  
  12.   
  13. app.MainLoop()  


Our intention was to display a window without a minimise box. So we did not specify this flag in the style parameter. 

Size and Position 
We can specify the size of our application in two ways. We have a size parameter in the constructor of our widget or we can call the SetSize() method: 
set_size.py 
  1. #!/usr/bin/env python3  
  2. # -*- coding: utf-8 -*-  
  3.   
  4. # set_size.py  
  5.   
  6. import wx  
  7.   
  8.   
  9. class Example(wx.Frame):  
  10.   
  11.     def __init__(self, parent, title):  
  12.         super(Example, self).__init__(parent, title=title,  
  13.             size=(350250))  
  14.   
  15.   
  16. def main():  
  17.   
  18.     app = wx.App()  
  19.     ex = Example(None, title='Sizing')  
  20.     ex.Show()  
  21.     app.MainLoop()  
  22.   
  23.   
  24. if __name__ == '__main__':  
  25.     main()  
In this example, the application will be 350x200 px in size. In the constructor we set the width of the wx.Frame widget to 350 px. The height of the widget to 250 px. 

Similarly, we can position our application on the screen. By default the window is placed in the upper left corner of the screen. But it can differ on various OS platforms or even window managers. Some window managers place application windows themselves. Some of them do some optimisation, so that windows do not overlap. A programmer can position the window programmatically. We already saw a pos parameter in the constructor of our wx.Frame widget. By providing other than the default values, we can control the position ourselves: 
* Move(wx.Point point): move a window to the given position
* MoveXY(int x, int y): move a window to the given position
* SetPosition(wx.Point point): set the position of a window
* SetDimensions(x, y, width, height, sizeFlags): set the position and the size of a window

There are several methods to do this. 
moving.py 
  1. #!/usr/bin/env python3  
  2. # -*- coding: utf-8 -*-  
  3.   
  4. # moving.py  
  5.   
  6. import wx  
  7.   
  8.   
  9. class Example(wx.Frame):  
  10.   
  11.     def __init__(self, parent, title):  
  12.         super(Example, self).__init__(parent, title=title,  
  13.             size=(300200))  
  14.   
  15.         self.Move((800250))  
  16.   
  17.   
  18. def  main():  
  19.   
  20.     app = wx.App()  
  21.     ex = Example(None, title='Moving')  
  22.     ex.Show()  
  23.     app.MainLoop()  
  24.   
  25.   
  26. if __name__ == '__main__':  
  27.     main()  
There is one particular situation. We might want to display our window maximised. In this case, the window is positioned at (0, 0) and takes the whole screen. wxPython internally calculates the screen coordinates. To maximise our wx.Frame, we call the Maximize() method. 

Centering on the screen 
If we want to center our application on the screen, wxPython has a handy method. The Centre() method simply centers the window on the screen. No need to calculate the width and the height of the screen. Simply call the method: 
centering.py 
  1. #!/usr/bin/env python3  
  2. # -*- coding: utf-8 -*-  
  3.   
  4. # centering.py  
  5.   
  6. import wx  
  7.   
  8.   
  9. class Example(wx.Frame):  
  10.   
  11.     def __init__(self, parent, title):  
  12.         super(Example, self).__init__(parent, title=title,  
  13.             size=(300200))  
  14.   
  15.         self.Centre()  
  16.   
  17.   
  18. def main():  
  19.   
  20.     app = wx.App()  
  21.     ex = Example(None, title='Centering')  
  22.     ex.Show()  
  23.     app.MainLoop()  
  24.   
  25.   
  26. if __name__ == '__main__':  
  27.     main()  
In this example, we center a small window on the screen. In this chapter, we have created some simple code examples in wxPython. 

Supplement 
Next - wxPython - Menus and toolbars 
八款 Python GUI 開發框架 
WxPython Application Development Cookbook 
tutorialspoint - wxPython - Frame Class

[Git 文章收集] Differences between git merge and git rebase

Source From  Here Preface Merging and rebasing are the two most popular way to applying changes from one branch into another one. They bot...