Ví dụ về db-api trong python

Hướng dẫn này đề cập đến SQLAlchemy Core API nổi tiếng đã được sử dụng trong nhiều năm. Kể từ SQLAlchemy 1. 4, có hai kiểu sử dụng Lõi riêng biệt được gọi là và , kiểu sau thực hiện một số điều chỉnh chủ yếu trong lĩnh vực cách kiểm soát giao dịch cũng như thu hẹp các mẫu về cách thực thi cấu trúc câu lệnh SQL

Kế hoạch là trong SQLAlchemy 2. 0, những phần tử của 1. x style Việc sử dụng lõi sẽ bị xóa sau giai đoạn ngừng sử dụng kéo dài trong suốt 1. 4 loạt. Để sử dụng ORM, một số phần tử của 1. kiểu x sẽ vẫn khả dụng; . 0 tài liệu cho một tổng quan đầy đủ

Hướng dẫn ở đây có thể áp dụng cho những người dùng muốn tìm hiểu cách SQLAlchemy Core đã được sử dụng trong nhiều năm, đặc biệt là những người dùng làm việc với các ứng dụng hiện có hoặc tài liệu học tập liên quan trong 1. phong cách x

Để có phần giới thiệu về SQLAlchemy Core từ phiên bản 1 mới. 2/4. 0 phối cảnh, xem

Ngôn ngữ biểu thức SQLAlchemy trình bày một hệ thống biểu diễn các cấu trúc và biểu thức cơ sở dữ liệu quan hệ bằng cách sử dụng các cấu trúc Python. Các cấu trúc này được mô hình hóa để giống với các cấu trúc của cơ sở dữ liệu cơ bản nhất có thể, đồng thời cung cấp một chút trừu tượng về sự khác biệt triển khai khác nhau giữa các phụ trợ cơ sở dữ liệu. Mặc dù các cấu trúc cố gắng thể hiện các khái niệm tương đương giữa các phần phụ trợ với các cấu trúc nhất quán, nhưng chúng không che giấu các khái niệm hữu ích dành riêng cho các tập con cụ thể của phần phụ trợ. Do đó, Ngôn ngữ biểu thức trình bày một phương pháp viết các biểu thức SQL trung lập với phần phụ trợ, nhưng không cố gắng thực thi rằng các biểu thức đó là trung lập với phần phụ trợ

Ngôn ngữ biểu thức trái ngược với Trình ánh xạ quan hệ đối tượng, là một API riêng biệt được xây dựng trên Ngôn ngữ biểu thức. Trong khi ORM, được giới thiệu trong Hướng dẫn quan hệ đối tượng (1. x API), trình bày một mô hình sử dụng mức độ cao và trừu tượng, bản thân nó là một ví dụ về việc sử dụng Ngôn ngữ Biểu thức được áp dụng, Ngôn ngữ Biểu thức trình bày một hệ thống biểu diễn các cấu trúc nguyên thủy của cơ sở dữ liệu quan hệ một cách trực tiếp mà không cần ý kiến

Mặc dù có sự trùng lặp giữa các kiểu sử dụng của ORM và Ngôn ngữ biểu thức, nhưng những điểm tương đồng là bề ngoài hơn so với lúc đầu chúng có thể xuất hiện. Một cách tiếp cận cấu trúc và nội dung của dữ liệu từ góc độ của mô hình miền do người dùng xác định, mô hình này được duy trì và làm mới một cách minh bạch từ mô hình lưu trữ cơ bản của nó. Phương pháp khác tiếp cận nó từ quan điểm của lược đồ theo nghĩa đen và biểu diễn biểu thức SQL được cấu tạo rõ ràng thành các thông báo được cơ sở dữ liệu sử dụng riêng lẻ

Một ứng dụng thành công có thể được xây dựng chỉ bằng Ngôn ngữ biểu thức, mặc dù ứng dụng sẽ cần xác định hệ thống dịch các khái niệm ứng dụng của riêng mình thành các thông báo cơ sở dữ liệu riêng lẻ và từ các tập kết quả cơ sở dữ liệu riêng lẻ. Ngoài ra, một ứng dụng được xây dựng bằng ORM có thể, trong các tình huống nâng cao, thỉnh thoảng sử dụng Ngôn ngữ biểu thức trực tiếp ở một số khu vực nhất định yêu cầu tương tác cơ sở dữ liệu cụ thể

Hướng dẫn sau đây ở định dạng doctest, nghĩa là mỗi dòng

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
07 đại diện cho nội dung bạn có thể nhập tại dấu nhắc lệnh Python và văn bản sau đây đại diện cho giá trị trả về dự kiến. Hướng dẫn không có điều kiện tiên quyết

Kiểm tra phiên bản

Kiểm tra nhanh để xác minh rằng chúng tôi đang sử dụng ít nhất phiên bản 1. 4 của SQLAlchemy

>>> import sqlalchemy
>>> sqlalchemy.__version__  
1.4.0

Đang kết nối

Đối với hướng dẫn này, chúng tôi sẽ sử dụng cơ sở dữ liệu SQLite chỉ trong bộ nhớ. Đây là một cách dễ dàng để kiểm tra mọi thứ mà không cần phải xác định cơ sở dữ liệu thực tế ở bất kỳ đâu. Để kết nối chúng tôi sử dụng

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)

Cờ

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
09 là lối tắt để thiết lập ghi nhật ký SQLAlchemy, được thực hiện thông qua mô-đun
>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
10 tiêu chuẩn của Python. Khi nó được bật, chúng ta sẽ thấy tất cả SQL được tạo. Nếu bạn đang làm việc thông qua hướng dẫn này và muốn tạo ra ít đầu ra hơn, hãy đặt nó thành
>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
11. Hướng dẫn này sẽ định dạng SQL phía sau cửa sổ bật lên để nó không cản trở chúng ta;

Giá trị trả về của là một phiên bản của , và nó đại diện cho giao diện cốt lõi của cơ sở dữ liệu, được điều chỉnh thông qua a xử lý các chi tiết của cơ sở dữ liệu và đang được sử dụng. Trong trường hợp này, phương ngữ SQLite sẽ diễn giải các hướng dẫn cho mô-đun

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
14 tích hợp sẵn của Python

Lần đầu tiên một phương thức như hoặc được gọi, nó sẽ thiết lập một kết nối thực sự với cơ sở dữ liệu, sau đó được sử dụng để phát ra SQL

Xác định và tạo bảng

Ngôn ngữ biểu thức SQL xây dựng các biểu thức của nó trong hầu hết các trường hợp đối với các cột của bảng. Trong SQLAlchemy, một cột thường được đại diện bởi một đối tượng có tên là , và trong mọi trường hợp a được liên kết với một. Một tập hợp các đối tượng và các đối tượng con liên quan của chúng được gọi là siêu dữ liệu cơ sở dữ liệu. Trong hướng dẫn này, chúng tôi sẽ trình bày rõ ràng một số đối tượng, nhưng lưu ý rằng SA cũng có thể tự động “nhập” toàn bộ bộ đối tượng từ cơ sở dữ liệu hiện có (quá trình này được gọi là phản ánh bảng)

Chúng tôi xác định tất cả các bảng của mình trong một danh mục có tên là , sử dụng cấu trúc, tương tự như các câu lệnh SQL CREATE TABLE thông thường. Chúng ta sẽ tạo hai bảng, một trong số đó đại diện cho “người dùng” trong một ứng dụng và một bảng khác đại diện cho 0 hoặc nhiều “địa chỉ email” cho mỗi hàng trong bảng “người dùng”

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )

Tất cả về cách xác định đối tượng, cũng như cách tự động tạo chúng từ cơ sở dữ liệu hiện có, được mô tả trong Mô tả cơ sở dữ liệu bằng siêu dữ liệu

Tiếp theo, để nói rằng chúng tôi thực sự muốn tạo lựa chọn bảng thực sự bên trong cơ sở dữ liệu SQLite, chúng tôi sử dụng , chuyển cho nó phiên bản

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
29 trỏ đến cơ sở dữ liệu của chúng tôi. Điều này sẽ kiểm tra sự hiện diện của từng bảng trước khi tạo, vì vậy sẽ an toàn khi gọi nhiều lần

sql>>> metadata_obj.create_all(engine)

Ghi chú

Người dùng quen thuộc với cú pháp của CREATE TABLE có thể nhận thấy rằng các cột VARCHAR được tạo không có độ dài; . Vì vậy, nếu chạy hướng dẫn này trên một trong những cơ sở dữ liệu đó, và bạn muốn sử dụng SQLAlchemy để phát hành CREATE TABLE, thì một "độ dài" có thể được cung cấp cho loại như bên dưới

Column("name", String(50))

Trường độ dài trên , cũng như các trường độ chính xác/tỷ lệ tương tự có sẵn trên , , v.v. không được tham chiếu bởi SQLAlchemy ngoài khi tạo bảng

Ngoài ra, Firebird và Oracle yêu cầu các trình tự để tạo mã định danh khóa chính mới và SQLAlchemy không tạo hoặc giả định các mã này mà không được hướng dẫn. Đối với điều đó, bạn sử dụng cấu trúc

from sqlalchemy import Sequence

Column("id", Integer, Sequence("user_id_seq"), primary_key=True)

Do đó, đầy đủ, hoàn hảo là

users = Table(
    "users",
    metadata_obj,
    Column("id", Integer, Sequence("user_id_seq"), primary_key=True),
    Column("name", String(50)),
    Column("fullname", String(50)),
    Column("nickname", String(50)),
)

Chúng tôi bao gồm cấu trúc dài dòng hơn này một cách riêng biệt để làm nổi bật sự khác biệt giữa cấu trúc tối thiểu chủ yếu chỉ hướng tới việc sử dụng trong Python, so với cấu trúc sẽ được sử dụng để phát ra các câu lệnh CREATE TABLE trên một nhóm phụ trợ cụ thể với các yêu cầu nghiêm ngặt hơn

Chèn biểu thức

Biểu thức SQL đầu tiên chúng ta sẽ tạo là cấu trúc, đại diện cho một câu lệnh INSERT. Điều này thường được tạo liên quan đến bảng mục tiêu của nó

Để xem mẫu SQL mà cấu trúc này tạo ra, hãy sử dụng hàm

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
38

>>> str(ins)
'INSERT INTO users (id, name, fullname) VALUES (:id, :name, :fullname)'

Lưu ý ở trên rằng câu lệnh INSERT đặt tên cho mọi cột trong bảng

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
39. Điều này có thể được hạn chế bằng cách sử dụng phương thức
>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
40, thiết lập mệnh đề VALUES của INSERT một cách rõ ràng

>>> ins = users.insert().values(name="jack", fullname="Jack Jones")
>>> str(ins)
'INSERT INTO users (name, fullname) VALUES (:name, :fullname)'

Ở trên, trong khi phương pháp

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
41 giới hạn mệnh đề GIÁ TRỊ chỉ trong hai cột, thì dữ liệu thực tế mà chúng tôi đã đặt trong
>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
41 không được hiển thị thành chuỗi; . Hóa ra, dữ liệu của chúng tôi được lưu trữ trong cấu trúc của chúng tôi, nhưng nó thường chỉ xuất hiện khi câu lệnh thực sự được thực thi; . Bây giờ chúng ta có thể xem qua dữ liệu này bằng cách xem biểu mẫu đã biên dịch của câu lệnh

>>> ins.compile().params  
{'fullname': 'Jack Jones', 'name': 'jack'}

thi hành

Phần thú vị của an là thực hiện nó. Điều này được thực hiện bằng cách sử dụng kết nối cơ sở dữ liệu, được đại diện bởi đối tượng. Để có được một kết nối, chúng tôi sẽ sử dụng phương pháp

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
0

Đối tượng đại diện cho tài nguyên kết nối DBAPI đã được kiểm tra tích cực. Hãy cho nó ăn đối tượng của chúng ta và xem điều gì sẽ xảy ra

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
1

Vì vậy, câu lệnh INSERT hiện đã được cấp cho cơ sở dữ liệu. Mặc dù chúng tôi có các tham số liên kết “qmark” theo vị trí thay vì các tham số liên kết “có tên” trong đầu ra. Làm thế nào mà ? . Chúng ta có thể xem thủ công như sau

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
2

Thế còn biến

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
51 mà chúng ta nhận được khi gọi là
>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
52 thì sao? . Trong trường hợp INSERT, chúng ta có thể lấy thông tin quan trọng từ nó, chẳng hạn như các giá trị khóa chính được tạo từ câu lệnh của chúng ta bằng cách sử dụng

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
3

Giá trị của

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
56 được tạo tự động bởi SQLite, nhưng chỉ vì chúng tôi không chỉ định cột
>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
57 trong câu lệnh của mình; . Trong cả hai trường hợp, SQLAlchemy luôn biết cách lấy giá trị khóa chính mới được tạo, mặc dù phương pháp tạo chúng là khác nhau giữa các cơ sở dữ liệu khác nhau; . Các phương pháp ở đây bao gồm từ việc sử dụng
>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
61, đến việc chọn từ một chức năng dành riêng cho cơ sở dữ liệu, đến việc sử dụng cú pháp
>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
62;

Thực thi nhiều câu lệnh

Ví dụ chèn của chúng tôi ở trên được cố ý rút ra một chút để hiển thị một số hành vi khác nhau của cấu trúc ngôn ngữ biểu thức. Trong trường hợp thông thường, một câu lệnh thường được biên dịch dựa trên các tham số được gửi đến phương thức

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
52 trên , do đó không cần sử dụng từ khóa ________0____41 với. Hãy tạo lại một câu lệnh chung và sử dụng nó theo cách “bình thường”

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
4

Ở trên, vì chúng tôi đã chỉ định cả ba cột trong phương thức

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
52, nên phần biên dịch bao gồm cả ba cột. Câu lệnh được biên dịch tại thời điểm thực hiện dựa trên các tham số chúng tôi đã chỉ định;

Để phát hành nhiều phần chèn bằng phương pháp

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
73 của DBAPI, chúng tôi có thể gửi danh sách từ điển, mỗi từ điển chứa một bộ tham số riêng biệt sẽ được chèn vào, như chúng tôi làm ở đây để thêm một số địa chỉ email

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
5

Ở trên, chúng tôi lại dựa vào việc tạo tự động các mã định danh khóa chính của SQLite cho mỗi hàng

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
74

Khi thực hiện nhiều bộ tham số, mỗi từ điển phải có cùng một bộ khóa; . e. bạn không thể có ít khóa hơn trong một số từ điển hơn những từ điển khác. Điều này là do câu lệnh được biên dịch theo từ điển đầu tiên trong danh sách và giả định rằng tất cả các từ điển đối số tiếp theo đều tương thích với câu lệnh đó

Phong cách gọi "executemany" có sẵn cho từng cấu trúc , và

lựa chọn

Chúng tôi đã bắt đầu với các phần chèn để cơ sở dữ liệu thử nghiệm của chúng tôi có một số dữ liệu trong đó. Phần thú vị hơn của dữ liệu là chọn nó. Chúng tôi sẽ đề cập đến các câu lệnh CẬP NHẬT và XÓA sau. Cấu trúc chính được sử dụng để tạo câu lệnh SELECT là hàm

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
6

Ở trên, chúng tôi đã thực hiện một cuộc gọi cơ bản, đặt bảng

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
39 trong mệnh đề COLUMNS của lựa chọn, sau đó thực hiện. SQLAlchemy đã mở rộng bảng
>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
39 thành tập hợp của từng cột của nó và cũng tạo ra mệnh đề TỪ cho chúng tôi

Kết quả trả về lại là một đối tượng, hoạt động giống như một con trỏ DBAPI, bao gồm các phương thức như và. Các phương thức này trả về các đối tượng hàng, được cung cấp thông qua lớp. Đối tượng kết quả có thể được lặp trực tiếp để cung cấp một trình lặp của các đối tượng

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
7

Ở trên, chúng ta thấy rằng việc in từng cái tạo ra một kết quả giống như bộ dữ liệu đơn giản. Cách chính tắc nhất trong Python để truy cập các giá trị của các bộ dữ liệu này khi các hàng được tìm nạp là thông qua phép gán bộ dữ liệu

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
8

Đối tượng thực sự hoạt động giống như một bộ có tên Python, vì vậy chúng ta cũng có thể truy cập các thuộc tính này từ chính hàng đó bằng cách sử dụng quyền truy cập thuộc tính

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
9

Để truy cập các cột thông qua tên bằng cách sử dụng chuỗi, khi tên cột được tạo theo chương trình hoặc chứa các ký tự không phải mã ascii, chế độ xem có thể được sử dụng để cung cấp quyền truy cập giống như từ điển

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
0

Thay đổi trong phiên bản 1. 4. Đã thêm cung cấp quyền truy cập giống như từ điển vào một , thay thế việc sử dụng trực tiếp các khóa chuỗi/cột đối với đối tượng

Vì là một bộ nên dãy (i. e. quyền truy cập số nguyên hoặc lát) cũng có thể được sử dụng

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
1

Một phương pháp truy cập cột chuyên biệt hơn là sử dụng cấu trúc SQL tương ứng trực tiếp với một cột cụ thể làm khóa ánh xạ;

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
2

Đối tượng có hành vi "tự động đóng" để đóng đối tượng DBAPI

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
98 bên dưới khi tất cả các hàng kết quả đang chờ xử lý đã được tìm nạp. Nếu a bị loại bỏ trước khi tự động đóng như vậy xảy ra, nó có thể được đóng một cách rõ ràng bằng phương thức

Chọn các cột cụ thể

Nếu chúng tôi muốn kiểm soát cẩn thận hơn các cột được đặt trong mệnh đề COLUMNS của phần chọn, chúng tôi sẽ tham chiếu các đối tượng riêng lẻ từ. Chúng có sẵn dưới dạng thuộc tính được đặt tên ngoài thuộc tính

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
03 của đối tượng

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
3

Hãy quan sát điều gì đó thú vị về mệnh đề TỪ. Trong khi câu lệnh được tạo có chứa hai phần riêng biệt, phần “CHỌN cột” và phần “TỪ bảng”, cấu trúc của chúng tôi chỉ có một danh sách chứa các cột. Cái này hoạt động ra sao ?

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
4

Nó đặt cả hai bảng vào mệnh đề TỪ. Nhưng ngoài ra, nó đã tạo ra một mớ hỗn độn thực sự. Những người quen thuộc với phép nối SQL biết rằng đây là một sản phẩm của Cartesian; . Vì vậy, để đưa một số sự tỉnh táo vào tuyên bố này, chúng ta cần một mệnh đề WHERE. Chúng tôi làm điều đó bằng cách sử dụng

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
5

Vì vậy, điều đó có vẻ tốt hơn rất nhiều, chúng tôi đã thêm một biểu thức vào biểu thức của chúng tôi, biểu thức này có tác dụng thêm

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
11 vào câu lệnh của chúng tôi và kết quả của chúng tôi đã được quản lý sao cho việc nối các hàng
>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
39 và
>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
74 có ý nghĩa. Nhưng hãy nhìn vào biểu hiện đó? . Rõ ràng là có chuyện gì đó đang xảy ra. Nói
>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
15 tạo ra
>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
16 và
>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
17 tạo ra
>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
11, không phải mệnh đề WHERE. Vì vậy, hãy xem chính xác biểu thức đó đang làm gì

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
6

Chà, bất ngờ. Đây không phải là

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
16 cũng không phải là
>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
11. Vâng nó là gì?

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
7

Như bạn có thể thấy, toán tử

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
21 đang tạo ra một đối tượng rất giống với các đối tượng và mà chúng ta đã tạo cho đến nay, nhờ vào nội dung dựng sẵn
>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
24 của Python; . Đến bây giờ, người ta có thể thấy rằng mọi thứ chúng ta đang làm việc cuối cùng đều là cùng một loại đối tượng. SQLAlchemy gọi lớp cơ sở của tất cả các biểu thức này là

nhà điều hành

Vì chúng ta đã tình cờ phát hiện ra mô hình toán tử của SQLAlchemy, chúng ta hãy xem qua một số khả năng của nó. Chúng ta đã thấy cách cân bằng hai cột với nhau

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
8

Nếu chúng ta sử dụng một giá trị theo nghĩa đen (nghĩa đen, không phải đối tượng mệnh đề SQLAlchemy), chúng ta sẽ nhận được một tham số liên kết

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
9

Chữ

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
27 được nhúng vào kết quả;

sql>>> metadata_obj.create_all(engine)
0

Hóa ra, hầu hết các toán tử Python tạo ra một biểu thức SQL ở đây, như bằng, không bằng, v.v.

sql>>> metadata_obj.create_all(engine)
1

Nếu chúng ta cộng hai cột số nguyên với nhau, chúng ta sẽ nhận được một biểu thức cộng

sql>>> metadata_obj.create_all(engine)
2

Thật thú vị, loại của là quan trọng. Nếu chúng tôi sử dụng

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
31 với hai cột dựa trên chuỗi (hãy nhớ rằng chúng tôi đặt các loại like và trên các đối tượng của chúng tôi ngay từ đầu), chúng tôi sẽ nhận được một cái gì đó khác biệt

sql>>> metadata_obj.create_all(engine)
3

Trong đó

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
35 là toán tử nối chuỗi được sử dụng trên hầu hết các cơ sở dữ liệu. Nhưng không phải tất cả trong số họ. Người dùng MySQL, đừng sợ

sql>>> metadata_obj.create_all(engine)
4

Phần trên minh họa SQL được tạo cho một cơ sở dữ liệu được kết nối với cơ sở dữ liệu MySQL;

Nếu bạn gặp một toán tử thực sự không khả dụng, bạn luôn có thể sử dụng phương pháp này;

sql>>> metadata_obj.create_all(engine)
5

Chức năng này cũng có thể được sử dụng để làm rõ ràng các toán tử bitwise. Ví dụ

là AND theo bit của giá trị trong

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
40

Khi sử dụng , kiểu trả về của biểu thức có thể quan trọng, đặc biệt khi toán tử được sử dụng trong biểu thức sẽ được gửi dưới dạng cột kết quả. Đối với trường hợp này, hãy đảm bảo loại rõ ràng, nếu không phải là loại thường được mong đợi, sử dụng

sql>>> metadata_obj.create_all(engine)
6

Đối với các toán tử boolean, hãy sử dụng phương thức này, phương thức này sẽ đảm bảo rằng kiểu trả về của biểu thức được xử lý dưới dạng boolean

sql>>> metadata_obj.create_all(engine)
7

Các toán tử thường được sử dụng

Dưới đây là danh sách một số toán tử phổ biến nhất được sử dụng trong cả ngôn ngữ biểu thức Core cũng như trong ORM. Ở đây chúng ta thấy các biểu thức thường xuất hiện nhất khi sử dụng phương thức, nhưng cũng có thể được sử dụng trong các tình huống khác

Danh sách tất cả các hoạt động cấp độ cột chung cho tất cả các đối tượng giống như cột có tại

Ghi chú

hầu hết các chương trình phụ trợ không hỗ trợ trực tiếp ILIKE. Đối với những trường hợp đó, toán tử hiển thị một biểu thức kết hợp LIKE với hàm LOWER SQL được áp dụng cho mỗi toán hạng

  • :

    sql>>> metadata_obj.create_all(engine)
    
    8

  • :

    sql>>> metadata_obj.create_all(engine)
    
    9

  • :

    Column("name", String(50))
    0

  • :

    Column("name", String(50))
    1

  • :

    Column("name", String(50))
    2

Ghi chú

Đảm bảo rằng bạn sử dụng chứ không phải toán tử

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
53 của Python

  • :

    Column("name", String(50))
    3

Ghi chú

Đảm bảo rằng bạn sử dụng chứ không phải toán tử

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
56 của Python

Ghi chú

sử dụng hàm

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
58 hoặc
>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
59 dành riêng cho cơ sở dữ liệu;

Tùy chỉnh nhà điều hành

Mặc dù rất thuận tiện để nhanh chóng có được một nhà điều hành tùy chỉnh, Core hỗ trợ tùy chỉnh cơ bản và mở rộng hệ thống nhà điều hành ở cấp độ loại. Hành vi của các toán tử hiện có có thể được sửa đổi trên cơ sở từng loại và các hoạt động mới có thể được xác định sẽ khả dụng cho tất cả các biểu thức cột là một phần của loại cụ thể đó. Xem phần mô tả

liên từ

Chúng tôi muốn giới thiệu một số toán tử của chúng tôi bên trong các cấu trúc. Nhưng chúng ta cần gộp chúng lại với nhau thêm một chút, vì vậy trước tiên hãy giới thiệu một số liên từ. Liên từ là những từ nhỏ như AND và OR ghép các thứ lại với nhau. Chúng tôi cũng sẽ đánh vào KHÔNG. , và có thể hoạt động từ các hàm tương ứng mà SQLAlchemy cung cấp (lưu ý rằng chúng tôi cũng đưa vào một )

Column("name", String(50))
4

Và bạn cũng có thể sử dụng các toán tử AND, OR và NOT được sắp xếp lại theo từng bit, mặc dù do ưu tiên của toán tử Python, bạn phải xem dấu ngoặc đơn của mình

Column("name", String(50))
5

Vì vậy, với tất cả từ vựng này, hãy chọn tất cả người dùng có địa chỉ email tại AOL hoặc MSN, có tên bắt đầu bằng một chữ cái giữa “m” và “z”, đồng thời chúng ta cũng sẽ tạo một cột chứa tên đầy đủ của họ kết hợp với . Chúng tôi sẽ thêm hai cấu trúc mới vào câu lệnh này và. tạo mệnh đề BETWEEN và được sử dụng trong biểu thức cột để tạo nhãn bằng từ khóa

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
70;

Column("name", String(50))
6

Một lần nữa, SQLAlchemy đã tìm ra mệnh đề TỪ cho câu lệnh của chúng ta. Trên thực tế, nó sẽ xác định mệnh đề TỪ dựa trên tất cả các bit khác của nó;

Một lối tắt để sử dụng là xâu chuỗi nhiều mệnh đề lại với nhau. Ở trên cũng có thể được viết là

Column("name", String(50))
7

Cách mà chúng ta có thể xây dựng một cấu trúc thông qua các lệnh gọi phương thức liên tiếp được gọi là

Sử dụng SQL văn bản

Ví dụ cuối cùng của chúng tôi thực sự đã trở thành một số ít để gõ. Đi từ những gì người ta hiểu là một biểu thức SQL văn bản thành một cấu trúc Python nhóm các thành phần lại với nhau theo kiểu lập trình có thể khó. Đó là lý do tại sao SQLAlchemy cho phép bạn chỉ sử dụng các chuỗi, đối với những trường hợp khi SQL đã được biết và không cần câu lệnh hỗ trợ các tính năng động. Cấu trúc được sử dụng để soạn một câu lệnh văn bản được chuyển đến cơ sở dữ liệu hầu như không thay đổi. Dưới đây, chúng tôi tạo một đối tượng và thực hiện nó

Column("name", String(50))
8

Ở trên, chúng ta có thể thấy rằng các tham số ràng buộc được chỉ định bằng cách sử dụng định dạng dấu hai chấm được đặt tên; . Để gửi giá trị cho các tham số, chúng tôi đã chuyển chúng vào phương thức dưới dạng đối số bổ sung

Chỉ định hành vi tham số ràng buộc

Cấu trúc hỗ trợ các giá trị giới hạn được thiết lập trước bằng phương thức

Column("name", String(50))
9

Các tham số cũng có thể được gõ rõ ràng

from sqlalchemy import Sequence

Column("id", Integer, Sequence("user_id_seq"), primary_key=True)
0

Việc nhập các tham số bị ràng buộc là cần thiết khi loại yêu cầu xử lý phía Python hoặc phía SQL đặc biệt được cung cấp bởi kiểu dữ liệu

Chỉ định hành vi cột kết quả

Chúng tôi cũng có thể chỉ định thông tin về các cột kết quả bằng phương thức;

from sqlalchemy import Sequence

Column("id", Integer, Sequence("user_id_seq"), primary_key=True)
1

hoặc nó có thể được chuyển các biểu thức cột đầy đủ theo vị trí, được nhập hoặc không được nhập. Trong trường hợp này, bạn nên liệt kê rõ ràng các cột trong SQL nguyên văn của mình, vì mối tương quan giữa các biểu thức cột của chúng ta với SQL sẽ được thực hiện theo vị trí

from sqlalchemy import Sequence

Column("id", Integer, Sequence("user_id_seq"), primary_key=True)
2

Khi chúng tôi gọi phương thức, chúng tôi nhận lại một đối tượng

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
82 hỗ trợ bộ đầy đủ của
>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
83 và các hoạt động “có thể lựa chọn” khác

from sqlalchemy import Sequence

Column("id", Integer, Sequence("user_id_seq"), primary_key=True)
3

Dạng vị trí của đặc biệt hữu ích khi liên kết SQL văn bản với các mô hình Core hoặc ORM hiện có, bởi vì chúng ta có thể sử dụng trực tiếp các biểu thức cột mà không phải lo lắng về xung đột tên hoặc các vấn đề khác với tên cột kết quả trong SQL văn bản

from sqlalchemy import Sequence

Column("id", Integer, Sequence("user_id_seq"), primary_key=True)
4

Ở trên, có ba cột trong kết quả được đặt tên là "id", nhưng vì chúng ta đã liên kết những cột này với các biểu thức cột theo vị trí nên tên không phải là vấn đề khi các cột kết quả được tìm nạp bằng cách sử dụng đối tượng cột thực tế làm khóa. Tìm nạp cột

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
85 sẽ là

from sqlalchemy import Sequence

Column("id", Integer, Sequence("user_id_seq"), primary_key=True)
5

Mặt khác, nếu chúng tôi sử dụng khóa cột chuỗi, các quy tắc khớp dựa trên tên thông thường vẫn được áp dụng và chúng tôi sẽ nhận được lỗi cột không rõ ràng cho giá trị

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
57

from sqlalchemy import Sequence

Column("id", Integer, Sequence("user_id_seq"), primary_key=True)
6

Điều quan trọng cần lưu ý là trong khi việc truy cập các cột từ một tập hợp kết quả bằng cách sử dụng các đối tượng có vẻ không bình thường, thì trên thực tế, đó là hệ thống duy nhất được ORM sử dụng, xảy ra trong suốt bên dưới mặt ngoài của đối tượng; . Ví dụ tại minh họa một cách sử dụng đơn giản

Mới trong phiên bản 1. 1. Phương pháp hiện chấp nhận các biểu thức cột sẽ được so khớp theo vị trí với tập kết quả SQL văn bản thuần túy, loại bỏ nhu cầu tên cột khớp hoặc thậm chí là duy nhất trong câu lệnh SQL khi khớp siêu dữ liệu bảng hoặc mô hình ORM với SQL văn bản

Sử dụng các đoạn văn bản () bên trong các câu lệnh lớn hơn

cũng có thể được sử dụng để tạo các đoạn SQL có thể tự do trong một đối tượng, chấp nhận các đối tượng làm đối số cho hầu hết các hàm xây dựng của nó. Dưới đây, chúng tôi kết hợp việc sử dụng bên trong một đối tượng. Cấu trúc cung cấp "hình học" của câu lệnh và cấu trúc cung cấp nội dung văn bản trong biểu mẫu này. Chúng tôi có thể xây dựng một tuyên bố mà không cần tham khảo bất kỳ siêu dữ liệu được thiết lập trước nào

from sqlalchemy import Sequence

Column("id", Integer, Sequence("user_id_seq"), primary_key=True)
7

Mặc dù có thể được sử dụng trong danh sách cột của một đối tượng, nhưng nó có một số hạn chế khi soạn lựa chọn được tạo, vì nó sẽ không có trong bộ sưu tập và sẽ bị loại bỏ khỏi bộ sưu tập các truy vấn con

sql>>> metadata_obj.create_all(engine)
02. Phần tiếp theo sẽ giới thiệu cấu trúc là lựa chọn tốt hơn để biểu thị các tên cột riêng lẻ dưới dạng các đoạn SQL

Chúng ta cũng có thể di chuyển mức cấu trúc của mình trở lại theo hướng khác bằng cách sử dụng , và cho một số thành phần chính của câu lệnh của chúng ta. Sử dụng các cấu trúc này, chúng tôi có thể nhận được nhiều khả năng biểu đạt hơn so với khi chúng tôi sử dụng trực tiếp, vì chúng cung cấp cho Lõi nhiều thông tin hơn về cách sử dụng các chuỗi mà chúng lưu trữ, nhưng vẫn không cần phải truy cập vào siêu dữ liệu dựa trên đầy đủ. Dưới đây, chúng tôi cũng chỉ định kiểu dữ liệu cho hai trong số các đối tượng chính để toán tử nối chuỗi cụ thể có sẵn. Chúng tôi cũng sử dụng để sử dụng các biểu thức đủ điều kiện bảng, e. g.

sql>>> metadata_obj.create_all(engine)
12, sẽ được hiển thị nguyên trạng;

from sqlalchemy import Sequence

Column("id", Integer, Sequence("user_id_seq"), primary_key=True)
8

Sắp xếp hoặc nhóm theo nhãn

Một nơi mà đôi khi chúng ta muốn sử dụng một chuỗi làm lối tắt là khi câu lệnh của chúng ta có một số thành phần cột được gắn nhãn mà chúng ta muốn tham chiếu đến ở một nơi chẳng hạn như mệnh đề “ORDER BY” hoặc “GROUP BY”; . Nếu chúng tôi có một nhãn như vậy trong cấu trúc của mình, chúng tôi có thể tham chiếu trực tiếp đến nó bằng cách chuyển thẳng chuỗi vào

sql>>> metadata_obj.create_all(engine)
15 hoặc
sql>>> metadata_obj.create_all(engine)
16, trong số những nhãn khác. Điều này sẽ đề cập đến nhãn được đặt tên và cũng ngăn không cho biểu thức được hiển thị hai lần. Tên nhãn phân giải thành cột được hiển thị đầy đủ

from sqlalchemy import Sequence

Column("id", Integer, Sequence("user_id_seq"), primary_key=True)
9

Chúng ta có thể sử dụng các công cụ sửa đổi như hoặc bằng cách chuyển tên chuỗi

users = Table(
    "users",
    metadata_obj,
    Column("id", Integer, Sequence("user_id_seq"), primary_key=True),
    Column("name", String(50)),
    Column("fullname", String(50)),
    Column("nickname", String(50)),
)
0

Lưu ý rằng tính năng chuỗi ở đây được điều chỉnh rất nhiều khi chúng tôi đã sử dụng phương thức này để tạo nhãn có tên cụ thể. Trong một số trường hợp khác, chúng ta luôn muốn quy chiếu trực tiếp đến đối tượng để hệ thống biểu đạt có thể đưa ra những lựa chọn kết xuất hiệu quả nhất. Dưới đây, chúng tôi minh họa cách sử dụng loại bỏ sự mơ hồ khi chúng tôi muốn sắp xếp theo tên cột xuất hiện nhiều lần

users = Table(
    "users",
    metadata_obj,
    Column("id", Integer, Sequence("user_id_seq"), primary_key=True),
    Column("name", String(50)),
    Column("fullname", String(50)),
    Column("nickname", String(50)),
)
1

Sử dụng bí danh và truy vấn phụ

Bí danh trong SQL tương ứng với phiên bản “được đổi tên” của bảng hoặc câu lệnh CHỌN, xảy ra bất cứ khi nào bạn nói “CHỌN. TỪ chỗ nào đó NHƯ cái tên nào đó”.

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
70 tạo tên mới cho bảng. Bí danh là một cấu trúc chính vì chúng cho phép bất kỳ bảng hoặc truy vấn con nào được tham chiếu bằng một tên duy nhất. Trong trường hợp của một bảng, điều này cho phép cùng một bảng được đặt tên trong mệnh đề TỪ nhiều lần. Trong trường hợp câu lệnh SELECT, nó cung cấp tên cha cho các cột được biểu thị bằng câu lệnh, cho phép chúng được tham chiếu tương ứng với tên này

Trong SQLAlchemy, bất kỳ hoặc tùy chọn dựa trên nào khác có thể được chuyển thành bí danh bằng cách sử dụng phương thức tạo ra cấu trúc. là một đối tượng tham chiếu đến ánh xạ các đối tượng thông qua tập hợp của nó và có thể được sử dụng trong mệnh đề TỪ của bất kỳ câu lệnh CHỌN nào tiếp theo, bằng cách tham chiếu đến các phần tử cột của nó trong các cột hoặc mệnh đề WHERE của câu lệnh hoặc thông qua vị trí rõ ràng trong

Ví dụ: giả sử chúng tôi biết rằng người dùng của chúng tôi

sql>>> metadata_obj.create_all(engine)
31 có hai địa chỉ email cụ thể. Làm cách nào chúng tôi có thể xác định vị trí giắc cắm dựa trên sự kết hợp của hai địa chỉ đó? . Chúng tôi tạo hai cấu trúc đối với
>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
74, sau đó sử dụng cả hai cấu trúc đó trong một cấu trúc

users = Table(
    "users",
    metadata_obj,
    Column("id", Integer, Sequence("user_id_seq"), primary_key=True),
    Column("name", String(50)),
    Column("fullname", String(50)),
    Column("nickname", String(50)),
)
2

Lưu ý rằng cấu trúc đã tạo ra các tên

sql>>> metadata_obj.create_all(engine)
37 và
sql>>> metadata_obj.create_all(engine)
38 trong kết quả SQL cuối cùng. Việc tạo các tên này được xác định bởi vị trí của cấu trúc trong câu lệnh. Nếu chúng ta tạo một truy vấn chỉ sử dụng bí danh thứ hai là
sql>>> metadata_obj.create_all(engine)
39, thì tên đó sẽ xuất hiện dưới dạng
sql>>> metadata_obj.create_all(engine)
37. Việc tạo tên cũng mang tính quyết định, nghĩa là cùng một cấu trúc câu lệnh SQLAlchemy sẽ tạo ra chuỗi SQL giống hệt nhau mỗi khi nó được hiển thị cho một phương ngữ cụ thể

Vì ở bên ngoài, chúng tôi đề cập đến bí danh bằng cách sử dụng chính cấu trúc, chúng tôi không cần quan tâm đến tên được tạo. Tuy nhiên, với mục đích gỡ lỗi, nó có thể được chỉ định bằng cách chuyển tên chuỗi cho phương thức

users = Table(
    "users",
    metadata_obj,
    Column("id", Integer, Sequence("user_id_seq"), primary_key=True),
    Column("name", String(50)),
    Column("fullname", String(50)),
    Column("nickname", String(50)),
)
3

Các cấu trúc hướng SELECT mở rộng từ có thể được biến thành các truy vấn con bí danh bằng cách sử dụng phương thức tạo ra một cấu trúc; . Giống như , cũng là một đối tượng có thể là một phần của bất kỳ CHỌN kèm theo nào bằng cách sử dụng các kỹ thuật tương tự mà người ta sẽ sử dụng cho một

Chúng ta có thể tự tham gia bảng

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
39 trở lại bảng mà chúng ta đã tạo bằng cách đưa ra toàn bộ câu lệnh

users = Table(
    "users",
    metadata_obj,
    Column("id", Integer, Sequence("user_id_seq"), primary_key=True),
    Column("name", String(50)),
    Column("fullname", String(50)),
    Column("nickname", String(50)),
)
4

Sử dụng tham gia

Chúng ta đã đi được nửa chặng đường để có thể xây dựng bất kỳ biểu thức SELECT nào. Nền tảng tiếp theo của CHỌN là biểu thức THAM GIA. Chúng tôi đã thực hiện phép nối trong các ví dụ của mình, bằng cách chỉ đặt hai bảng trong mệnh đề cột hoặc mệnh đề where của cấu trúc. Nhưng nếu chúng ta muốn tạo một cấu trúc “THAM GIA” hoặc “OUTERJOIN” thực sự, chúng ta sử dụng các phương thức và, thường được truy cập nhất từ ​​bảng bên trái trong phép nối

users = Table(
    "users",
    metadata_obj,
    Column("id", Integer, Sequence("user_id_seq"), primary_key=True),
    Column("name", String(50)),
    Column("fullname", String(50)),
    Column("nickname", String(50)),
)
5

Người đọc tỉnh táo sẽ thấy nhiều bất ngờ hơn; . Điều kiện BẬT của phép nối, như nó được gọi, được tạo tự động dựa trên đối tượng mà chúng ta đã đặt trên cách bảng

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
74 ở phần đầu của hướng dẫn này. Đã có cấu trúc
sql>>> metadata_obj.create_all(engine)
60 trông giống như một cách tốt hơn nhiều để tham gia các bảng

Tất nhiên, bạn có thể tham gia theo bất kỳ biểu thức nào bạn muốn, chẳng hạn như nếu chúng tôi muốn tham gia trên tất cả người dùng sử dụng cùng tên trong địa chỉ email làm tên người dùng của họ

users = Table(
    "users",
    metadata_obj,
    Column("id", Integer, Sequence("user_id_seq"), primary_key=True),
    Column("name", String(50)),
    Column("fullname", String(50)),
    Column("nickname", String(50)),
)
6

Khi chúng tôi tạo một cấu trúc, SQLAlchemy sẽ xem xét các bảng mà chúng tôi đã đề cập và sau đó đặt chúng vào mệnh đề TỪ của câu lệnh. Tuy nhiên, khi chúng tôi sử dụng THAM GIA, chúng tôi biết chúng tôi muốn mệnh đề TỪ nào, vì vậy ở đây chúng tôi sử dụng phương thức

users = Table(
    "users",
    metadata_obj,
    Column("id", Integer, Sequence("user_id_seq"), primary_key=True),
    Column("name", String(50)),
    Column("fullname", String(50)),
    Column("nickname", String(50)),
)
7

Phương thức này tạo ra các cấu trúc

sql>>> metadata_obj.create_all(engine)
64 và được sử dụng giống như

users = Table(
    "users",
    metadata_obj,
    Column("id", Integer, Sequence("user_id_seq"), primary_key=True),
    Column("name", String(50)),
    Column("fullname", String(50)),
    Column("nickname", String(50)),
)
8

Đó là kết quả mà

sql>>> metadata_obj.create_all(engine)
66 tạo ra, tất nhiên, trừ khi bạn bị mắc kẹt trong hợp đồng biểu diễn sử dụng Oracle trước phiên bản 9 và bạn đã thiết lập công cụ của mình (sẽ sử dụng
sql>>> metadata_obj.create_all(engine)
67) để sử dụng SQL dành riêng cho Oracle

users = Table(
    "users",
    metadata_obj,
    Column("id", Integer, Sequence("user_id_seq"), primary_key=True),
    Column("name", String(50)),
    Column("fullname", String(50)),
    Column("nickname", String(50)),
)
9

Nếu bạn không biết SQL nghĩa là gì, đừng lo lắng. Bộ tộc bí mật của Oracle DBA không muốn ma thuật đen của họ bị phát hiện;)

Biểu thức bảng chung (CTE)

Các biểu thức bảng phổ biến hiện được hỗ trợ bởi mọi cơ sở dữ liệu chính, bao gồm cả MySQL, MariaDB, SQLite, PostgreSQL, Oracle và MS SQL Server hiện đại. SQLAlchemy hỗ trợ cấu trúc này thông qua đối tượng, đối tượng này thường có được bằng cách sử dụng phương thức trên cấu trúc

>>> str(ins)
'INSERT INTO users (id, name, fullname) VALUES (:id, :name, :fullname)'
0

Cấu trúc CTE là một cách tuyệt vời để cung cấp nguồn hàng tương tự về mặt ngữ nghĩa với việc sử dụng truy vấn con, nhưng với định dạng đơn giản hơn nhiều trong đó nguồn hàng được giấu gọn gàng ở đầu truy vấn nơi có thể tham chiếu nó ở bất kỳ đâu trong

Khi chúng ta xây dựng một đối tượng, chúng ta sử dụng nó giống như bất kỳ bảng nào khác trong câu lệnh. Tuy nhiên, thay vì được thêm vào mệnh đề TỪ dưới dạng truy vấn con, nó lại xuất hiện ở trên cùng, điều này có lợi ích bổ sung là không gây bất ngờ cho tích cartesian

Định dạng RECURSIVE của CTE khả dụng khi một người sử dụng tham số. CTE đệ quy thường yêu cầu chúng tôi liên kết với chính mình dưới dạng bí danh. Hình thức chung của loại hoạt động này liên quan đến một UNION của CTE ban đầu chống lại chính nó. Lưu ý rằng các bảng ví dụ của chúng tôi không phù hợp để tạo ra một truy vấn thực sự hữu ích với tính năng này, biểu mẫu này trông giống như

>>> str(ins)
'INSERT INTO users (id, name, fullname) VALUES (:id, :name, :fullname)'
1

Mọi thứ khác

Các khái niệm về tạo biểu thức SQL đã được giới thiệu. Những gì còn lại là nhiều biến thể của cùng một chủ đề. Vì vậy, bây giờ chúng tôi sẽ lập danh mục những điều quan trọng còn lại mà chúng tôi cần biết

Đối tượng tham số ràng buộc

Xuyên suốt tất cả các ví dụ này, SQLAlchemy đang bận tạo các tham số liên kết ở bất cứ nơi nào xuất hiện các biểu thức bằng chữ. Bạn cũng có thể chỉ định các tham số liên kết của riêng mình bằng tên của riêng bạn và sử dụng lặp đi lặp lại cùng một câu lệnh. Cấu trúc được sử dụng để tạo tham số ràng buộc với tên đã cho. Mặc dù SQLAlchemy luôn đề cập đến các tham số bị ràng buộc theo tên ở phía API, phương ngữ cơ sở dữ liệu chuyển đổi thành kiểu có tên hoặc vị trí thích hợp tại thời điểm thực thi, như ở đây khi nó chuyển đổi thành vị trí cho SQLite

>>> str(ins)
'INSERT INTO users (id, name, fullname) VALUES (:id, :name, :fullname)'
2

Một khía cạnh quan trọng khác là nó có thể được gán một loại. Loại tham số liên kết sẽ xác định hành vi của nó trong các biểu thức và cả cách dữ liệu được liên kết với nó được xử lý trước khi được gửi đến cơ sở dữ liệu

>>> str(ins)
'INSERT INTO users (id, name, fullname) VALUES (:id, :name, :fullname)'
3

các cấu trúc cùng tên cũng có thể được sử dụng nhiều lần, trong đó chỉ cần một giá trị được đặt tên duy nhất trong các tham số thực thi

>>> str(ins)
'INSERT INTO users (id, name, fullname) VALUES (:id, :name, :fullname)'
4

Chức năng

Các hàm SQL được tạo bằng từ khóa, từ này tạo các hàm bằng truy cập thuộc tính

>>> str(ins)
'INSERT INTO users (id, name, fullname) VALUES (:id, :name, :fullname)'
5

Bằng cách "tạo", chúng tôi có nghĩa là bất kỳ hàm SQL nào được tạo dựa trên từ bạn chọn

>>> str(ins)
'INSERT INTO users (id, name, fullname) VALUES (:id, :name, :fullname)'
6

Một số tên hàm được biết bởi SQLAlchemy, cho phép áp dụng các quy tắc hành vi đặc biệt. Một số ví dụ là các hàm “ANSI”, có nghĩa là chúng không được thêm dấu ngoặc đơn sau chúng, chẳng hạn như CURRENT_TIMESTAMP

>>> str(ins)
'INSERT INTO users (id, name, fullname) VALUES (:id, :name, :fullname)'
7

Một hàm, giống như bất kỳ biểu thức cột nào khác, có một loại biểu thị loại biểu thức cũng như cách SQLAlchemy sẽ diễn giải các cột kết quả được trả về từ biểu thức này. Loại mặc định được sử dụng cho một tên hàm tùy ý bắt nguồn từ

sql>>> metadata_obj.create_all(engine)
76 chỉ đơn giản là một kiểu dữ liệu “null”. Tuy nhiên, để biểu thức cột do hàm tạo có hành vi của toán tử dành riêng cho loại cũng như các hành vi của tập hợp kết quả, chẳng hạn như các ràng buộc về ngày và số, thì loại có thể cần được chỉ định rõ ràng

>>> str(ins)
'INSERT INTO users (id, name, fullname) VALUES (:id, :name, :fullname)'
8

Các hàm thường được sử dụng nhất trong mệnh đề cột của câu lệnh chọn và cũng có thể được gắn nhãn cũng như được cung cấp một loại. Bạn nên gắn nhãn một hàm để kết quả có thể được nhắm mục tiêu trong một hàng kết quả dựa trên tên chuỗi và việc gán cho nó một loại là bắt buộc khi bạn cần xử lý tập hợp kết quả, chẳng hạn như chuyển đổi Unicode và chuyển đổi ngày. Dưới đây, chúng tôi sử dụng hàm kết quả

sql>>> metadata_obj.create_all(engine)
78 để chỉ đọc cột đầu tiên của hàng đầu tiên và sau đó đóng kết quả;

>>> str(ins)
'INSERT INTO users (id, name, fullname) VALUES (:id, :name, :fullname)'
9

Các cơ sở dữ liệu như PostgreSQL và Oracle hỗ trợ các hàm trả về toàn bộ tập kết quả có thể được tập hợp thành các đơn vị có thể lựa chọn, có thể được sử dụng trong các câu lệnh. Chẳng hạn, một hàm cơ sở dữ liệu

sql>>> metadata_obj.create_all(engine)
79 nhận các tham số
sql>>> metadata_obj.create_all(engine)
80 và
sql>>> metadata_obj.create_all(engine)
81, đồng thời trả về ba cột mà chúng tôi muốn đặt tên là
sql>>> metadata_obj.create_all(engine)
82,
sql>>> metadata_obj.create_all(engine)
83 và
sql>>> metadata_obj.create_all(engine)
84, chúng tôi có thể xây dựng bằng cách sử dụng các đối tượng cột “từ vựng” cũng như các tham số liên kết

>>> ins = users.insert().values(name="jack", fullname="Jack Jones")
>>> str(ins)
'INSERT INTO users (name, fullname) VALUES (:name, :fullname)'
0

Nếu chúng tôi muốn sử dụng câu lệnh

sql>>> metadata_obj.create_all(engine)
85 của mình hai lần với các tham số liên kết khác nhau, hàm sẽ tạo các bản sao cho chúng tôi và đánh dấu các tham số liên kết là "duy nhất" để các tên xung đột được tách biệt. Lưu ý rằng chúng tôi cũng tạo hai bí danh riêng biệt có thể chọn của chúng tôi

>>> ins = users.insert().values(name="jack", fullname="Jack Jones")
>>> str(ins)
'INSERT INTO users (name, fullname) VALUES (:name, :fullname)'
1

Chức năng cửa sổ

Bất kỳ , bao gồm các chức năng được tạo bởi , có thể được biến thành một “hàm cửa sổ”, đó là mệnh đề QUÁ, sử dụng phương thức

>>> ins = users.insert().values(name="jack", fullname="Jack Jones")
>>> str(ins)
'INSERT INTO users (name, fullname) VALUES (:name, :fullname)'
2

cũng hỗ trợ đặc tả phạm vi bằng cách sử dụng hoặc tham số

>>> ins = users.insert().values(name="jack", fullname="Jack Jones")
>>> str(ins)
'INSERT INTO users (name, fullname) VALUES (:name, :fullname)'
3

và mỗi bộ chấp nhận một bộ hai chứa tổ hợp các số nguyên âm và dương cho các phạm vi, số 0 để biểu thị “DÒNG HIỆN TẠI” và

sql>>> metadata_obj.create_all(engine)
95 để biểu thị “KHÔNG GIỚI HẠN”. Xem các ví dụ tại để biết thêm chi tiết

Mới trong phiên bản 1. 1. hỗ trợ đặc tả "hàng" và "phạm vi" cho các chức năng của cửa sổ

Truyền dữ liệu và ép kiểu

Trong SQL, chúng ta thường cần chỉ rõ kiểu dữ liệu của một phần tử hoặc chúng ta cần chuyển đổi giữa kiểu dữ liệu này sang kiểu dữ liệu khác trong câu lệnh SQL. Hàm CAST SQL thực hiện điều này. Trong SQLAlchemy, hàm hiển thị từ khóa SQL CAST. Nó chấp nhận một biểu thức cột và một đối tượng kiểu dữ liệu làm đối số

>>> ins = users.insert().values(name="jack", fullname="Jack Jones")
>>> str(ins)
'INSERT INTO users (name, fullname) VALUES (:name, :fullname)'
4

Hàm này không chỉ được sử dụng khi chuyển đổi giữa các kiểu dữ liệu mà còn trong trường hợp cơ sở dữ liệu cần biết rằng một số giá trị cụ thể nên được coi là thuộc một kiểu dữ liệu cụ thể trong một biểu thức

Hàm này cũng cho chính SQLAlchemy biết rằng một biểu thức cũng phải được coi là một loại cụ thể. Kiểu dữ liệu của một biểu thức tác động trực tiếp đến hành vi của các toán tử Python đối với đối tượng đó, chẳng hạn như cách toán tử

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata_obj = MetaData()
>>> users = Table(
..     "users",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("name", String),
..     Column("fullname", String),
.. )

>>> addresses = Table(
..     "addresses",
..     metadata_obj,
..     Column("id", Integer, primary_key=True),
..     Column("user_id", None, ForeignKey("users.id")),
..     Column("email_address", String, nullable=False),
.. )
31 có thể biểu thị phép cộng số nguyên hoặc nối chuỗi và nó cũng tác động đến cách một giá trị Python bằng chữ được chuyển đổi hoặc xử lý trước khi được chuyển đến cơ sở dữ liệu dưới dạng

Đôi khi, cần phải có SQLAlchemy biết kiểu dữ liệu của một biểu thức, vì tất cả các lý do được đề cập ở trên, nhưng để không hiển thị chính biểu thức CAST ở phía SQL, nơi nó có thể can thiệp vào hoạt động SQL đã hoạt động mà không có nó. Đối với trường hợp sử dụng khá phổ biến này, có một chức năng khác có liên quan chặt chẽ với , trong đó nó thiết lập một biểu thức Python có một loại cơ sở dữ liệu SQL cụ thể, nhưng không hiển thị từ khóa hoặc kiểu dữ liệu

Column("name", String(50))
03 ở phía cơ sở dữ liệu. đặc biệt quan trọng khi xử lý kiểu dữ liệu, kiểu này thường có mối quan hệ phức tạp với kiểu dữ liệu hướng chuỗi trên các nền tảng khác nhau và thậm chí có thể không phải là kiểu dữ liệu rõ ràng, chẳng hạn như trên SQLite và MariaDB. Dưới đây, chúng tôi sử dụng để cung cấp cấu trúc Python dưới dạng chuỗi JSON vào một trong các hàm JSON của MySQL

>>> ins = users.insert().values(name="jack", fullname="Jack Jones")
>>> str(ins)
'INSERT INTO users (name, fullname) VALUES (:name, :fullname)'
5

Ở trên, hàm SQL

Column("name", String(50))
07 của MySQL đã được gọi vì chúng tôi đã từng chỉ ra rằng từ điển Python của chúng tôi nên được coi là. Kết quả là toán tử
Column("name", String(50))
10 của Python, trong trường hợp này là
Column("name", String(50))
11, đã có sẵn và cho phép biểu thức đường dẫn
Column("name", String(50))
07 (không được hiển thị, tuy nhiên trong trường hợp này, cuối cùng nó sẽ là
Column("name", String(50))
13) được hiển thị

Công đoàn và các hoạt động tập hợp khác

Các liên kết có hai loại, UNION và UNION ALL, có sẵn thông qua các chức năng cấp mô-đun và

>>> ins = users.insert().values(name="jack", fullname="Jack Jones")
>>> str(ins)
'INSERT INTO users (name, fullname) VALUES (:name, :fullname)'
6

Cũng có sẵn, mặc dù không được hỗ trợ trên tất cả các cơ sở dữ liệu, là , , và

>>> ins = users.insert().values(name="jack", fullname="Jack Jones")
>>> str(ins)
'INSERT INTO users (name, fullname) VALUES (:name, :fullname)'
7

Một vấn đề phổ biến với cái gọi là các lựa chọn được gọi là "ghép" phát sinh do thực tế là chúng lồng với dấu ngoặc đơn. Đặc biệt SQLite không thích câu lệnh bắt đầu bằng dấu ngoặc đơn. Vì vậy, khi lồng một “hợp chất” bên trong một “hợp chất”, thường cần áp dụng

Column("name", String(50))
20 cho phần tử đầu tiên của hợp chất ngoài cùng, nếu phần tử đó cũng là một hợp chất. Ví dụ: để lồng một “union” và một “select” bên trong “ngoại trừ_”, SQLite sẽ muốn “union” được nêu dưới dạng truy vấn con

>>> ins = users.insert().values(name="jack", fullname="Jack Jones")
>>> str(ins)
'INSERT INTO users (name, fullname) VALUES (:name, :fullname)'
8

Công đoàn đặt hàng

UNION và các cấu trúc tập hợp khác có trường hợp đặc biệt khi sắp xếp thứ tự kết quả. Vì UNION bao gồm một số câu lệnh SELECT, để ĐẶT HÀNG toàn bộ kết quả thường yêu cầu mệnh đề ORDER BY đề cập đến tên cột chứ không phải bảng cụ thể. Như trong các ví dụ trước, chúng tôi đã sử dụng

Column("name", String(50))
21 nhưng SQLAlchemy đã hiển thị ORDER BY mà không sử dụng tên bảng. Một cách tổng quát để áp dụng ORDER BY cho một liên kết cũng là tham khảo bộ sưu tập
Column("name", String(50))
22 để truy cập các biểu thức cột đồng nghĩa với các cột được chọn từ SELECT đầu tiên;

>>> ins = users.insert().values(name="jack", fullname="Jack Jones")
>>> str(ins)
'INSERT INTO users (name, fullname) VALUES (:name, :fullname)'
9

Lựa chọn vô hướng

Một lựa chọn vô hướng là một CHỌN trả về chính xác một hàng và một cột. Sau đó nó có thể được sử dụng như một biểu thức cột. Một lựa chọn vô hướng thường là một , dựa trên câu lệnh SELECT kèm theo để có được ít nhất một trong các mệnh đề TỪ của nó

Cấu trúc có thể được sửa đổi để hoạt động như một biểu thức cột bằng cách gọi phương thức hoặc

>>> ins.compile().params  
{'fullname': 'Jack Jones', 'name': 'jack'}
0

Cấu trúc trên bây giờ là một đối tượng, là một bộ điều hợp xung quanh đối tượng

sql>>> metadata_obj.create_all(engine)
70 ban đầu; . Chúng ta có thể đặt cấu trúc này giống như bất kỳ cột nào khác trong cột khác

>>> ins.compile().params  
{'fullname': 'Jack Jones', 'name': 'jack'}
1

Để áp dụng một tên cột không ẩn danh cho lựa chọn vô hướng của chúng tôi, thay vào đó, chúng tôi tạo nó bằng cách sử dụng

>>> ins.compile().params  
{'fullname': 'Jack Jones', 'name': 'jack'}
2

Sắp xếp thứ tự, Nhóm, Giới hạn, Offset…ing…

Việc sắp xếp thứ tự được thực hiện bằng cách chuyển các biểu thức cột tới phương thức

Column("name", String(50))
31

>>> ins.compile().params  
{'fullname': 'Jack Jones', 'name': 'jack'}
3

Tăng dần hoặc giảm dần có thể được kiểm soát bằng cách sử dụng công cụ sửa đổi và

>>> ins.compile().params  
{'fullname': 'Jack Jones', 'name': 'jack'}
4

Nhóm đề cập đến mệnh đề GROUP BY và thường được sử dụng cùng với các hàm tổng hợp để thiết lập các nhóm hàng được tổng hợp. Điều này được cung cấp thông qua phương pháp

Column("name", String(50))
34

>>> ins.compile().params  
{'fullname': 'Jack Jones', 'name': 'jack'}
5

Xem thêm một kỹ thuật quan trọng để sắp xếp hoặc nhóm theo tên cột chuỗi

HAVING có thể được sử dụng để lọc kết quả trên một giá trị tổng hợp, sau khi đã áp dụng GROUP BY. Nó có sẵn ở đây thông qua phương thức

>>> ins.compile().params  
{'fullname': 'Jack Jones', 'name': 'jack'}
6

Một hệ thống phổ biến để xử lý các bản sao trong các câu lệnh CHỌN đã soạn là công cụ sửa đổi DISTINCT. Có thể thêm mệnh đề DISTINCT đơn giản bằng phương thức

>>> ins.compile().params  
{'fullname': 'Jack Jones', 'name': 'jack'}
7

Hầu hết các chương trình phụ trợ cơ sở dữ liệu đều hỗ trợ một hệ thống giới hạn số lượng hàng được trả về và phần lớn cũng có tính năng bắt đầu trả về các hàng sau một "độ lệch" nhất định. Mặc dù các chương trình phụ trợ phổ biến như PostgreSQL, MySQL và SQLite hỗ trợ các từ khóa LIMIT và OFFSET, nhưng các chương trình phụ trợ khác cần tham khảo các tính năng bí truyền hơn như “chức năng cửa sổ” và id hàng để đạt được hiệu quả tương tự. Các phương thức và cung cấp một sự trừu tượng dễ dàng vào phương pháp phụ trợ hiện tại

>>> ins.compile().params  
{'fullname': 'Jack Jones', 'name': 'jack'}
8

Chèn, cập nhật và xóa

Chúng tôi đã chứng minh trước đó trong hướng dẫn này. Trường hợp tạo INSERT, phương thức tạo CẬP NHẬT. Cả hai cấu trúc này đều có một phương thức được gọi là chỉ định mệnh đề VALUES hoặc SET của câu lệnh

Phương thức chứa bất kỳ biểu thức cột nào dưới dạng giá trị

>>> ins.compile().params  
{'fullname': 'Jack Jones', 'name': 'jack'}
9

Khi sử dụng hoặc trong ngữ cảnh “thực thi nhiều”, chúng tôi cũng có thể muốn chỉ định các tham số ràng buộc được đặt tên mà chúng tôi có thể tham khảo trong danh sách đối số. Hai cấu trúc sẽ tự động tạo các trình giữ chỗ bị ràng buộc cho bất kỳ tên cột nào được chuyển trong từ điển được gửi tới tại thời điểm thực thi. Tuy nhiên, nếu chúng tôi muốn sử dụng các tham số được đặt tên được nhắm mục tiêu rõ ràng với các biểu thức tổng hợp, chúng tôi cần sử dụng cấu trúc. Khi sử dụng with hoặc , bản thân tên của các cột trong bảng được dành riêng cho việc tạo tên liên kết "tự động". Chúng ta có thể kết hợp việc sử dụng các tên liên kết có sẵn ngầm định và các tham số được đặt tên rõ ràng như trong ví dụ dưới đây

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
00

Một câu lệnh CẬP NHẬT được phát ra bằng cách sử dụng cấu trúc. Điều này hoạt động giống như một INSERT, ngoại trừ có một mệnh đề WHERE bổ sung có thể được chỉ định

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
01

Khi sử dụng trong ngữ cảnh “executemany”, chúng ta cũng có thể muốn sử dụng các tham số ràng buộc được đặt tên rõ ràng trong mệnh đề WHERE. Một lần nữa, là cấu trúc được sử dụng để đạt được điều này

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
02

xóa

Cuối cùng, xóa. Điều này được thực hiện đủ dễ dàng bằng cách sử dụng cấu trúc

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
03

Xóa nhiều bảng

Tất cả các chương trình phụ trợ PostgreSQL, Microsoft SQL Server và MySQL đều hỗ trợ các câu lệnh DELETE tham chiếu đến nhiều bảng trong tiêu chí WHERE. Đối với PG và MySQL, đây là cú pháp “DELETE USING” và đối với SQL Server, đó là cú pháp “DELETE FROM” đề cập đến nhiều hơn một bảng. Cấu trúc SQLAlchemy hỗ trợ hoàn toàn cả hai chế độ này, bằng cách chỉ định nhiều bảng trong mệnh đề WHERE

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
04

Trên phần phụ trợ PostgreSQL, kết quả SQL từ câu lệnh trên sẽ hiển thị dưới dạng

>>> from sqlalchemy import create_engine
>>> engine = create_engine("sqlite:///:memory:", echo=True)
05

Khi cấu trúc được sử dụng trên cơ sở dữ liệu không hỗ trợ, trình biên dịch sẽ tăng

Column("name", String(50))
56. Để thuận tiện, khi một câu lệnh được in dưới dạng một chuỗi mà không có đặc điểm kỹ thuật của một phương ngữ, trình biên dịch “SQL chuỗi” sẽ được gọi để cung cấp một biểu diễn SQL không hoạt động của cấu trúc

Số lượng hàng phù hợp

Cả hai và được liên kết với số lượng hàng phù hợp. Đây là một số cho biết số lượng hàng được so khớp bởi mệnh đề WHERE. Lưu ý rằng bởi "khớp", điều này bao gồm các hàng không có CẬP NHẬT nào thực sự diễn ra. Giá trị có sẵn như