CARVIEW |
Select Language
HTTP/2 200
date: Wed, 30 Jul 2025 21:23:07 GMT
content-type: text/html; charset=utf-8
vary: X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, X-Requested-With,Accept-Encoding, Accept, X-Requested-With
etag: W/"9ecd0ea7174a3ca1ca286a1b064d5419"
cache-control: max-age=0, private, must-revalidate
strict-transport-security: max-age=31536000; includeSubdomains; preload
x-frame-options: deny
x-content-type-options: nosniff
x-xss-protection: 0
referrer-policy: no-referrer-when-downgrade
content-security-policy: default-src 'none'; base-uri 'self'; child-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/; connect-src 'self' uploads.github.com www.githubstatus.com collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com *.rel.tunnels.api.visualstudio.com wss://*.rel.tunnels.api.visualstudio.com objects-origin.githubusercontent.com copilot-proxy.githubusercontent.com proxy.individual.githubcopilot.com proxy.business.githubcopilot.com proxy.enterprise.githubcopilot.com *.actions.githubusercontent.com wss://*.actions.githubusercontent.com productionresultssa0.blob.core.windows.net/ productionresultssa1.blob.core.windows.net/ productionresultssa2.blob.core.windows.net/ productionresultssa3.blob.core.windows.net/ productionresultssa4.blob.core.windows.net/ productionresultssa5.blob.core.windows.net/ productionresultssa6.blob.core.windows.net/ productionresultssa7.blob.core.windows.net/ productionresultssa8.blob.core.windows.net/ productionresultssa9.blob.core.windows.net/ productionresultssa10.blob.core.windows.net/ productionresultssa11.blob.core.windows.net/ productionresultssa12.blob.core.windows.net/ productionresultssa13.blob.core.windows.net/ productionresultssa14.blob.core.windows.net/ productionresultssa15.blob.core.windows.net/ productionresultssa16.blob.core.windows.net/ productionresultssa17.blob.core.windows.net/ productionresultssa18.blob.core.windows.net/ productionresultssa19.blob.core.windows.net/ github-production-repository-image-32fea6.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com insights.github.com wss://alive.github.com wss://alive-staging.github.com api.githubcopilot.com api.individual.githubcopilot.com api.business.githubcopilot.com api.enterprise.githubcopilot.com; font-src github.githubassets.com; form-action 'self' github.com gist.github.com copilot-workspace.githubnext.com objects-origin.githubusercontent.com; frame-ancestors 'none'; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com; img-src 'self' data: blob: github.githubassets.com media.githubusercontent.com camo.githubusercontent.com identicons.github.com avatars.githubusercontent.com private-avatars.githubusercontent.com github-cloud.s3.amazonaws.com objects.githubusercontent.com release-assets.githubusercontent.com secured-user-images.githubusercontent.com/ user-images.githubusercontent.com/ private-user-images.githubusercontent.com opengraph.githubassets.com copilotprodattachments.blob.core.windows.net/github-production-copilot-attachments/ github-production-user-asset-6210df.s3.amazonaws.com customer-stories-feed.github.com spotlights-feed.github.com objects-origin.githubusercontent.com *.githubusercontent.com; manifest-src 'self'; media-src github.com user-images.githubusercontent.com/ secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com github-production-user-asset-6210df.s3.amazonaws.com gist.github.com; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com; upgrade-insecure-requests; worker-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/
server: github.com
content-encoding: gzip
accept-ranges: bytes
set-cookie: _gh_sess=T7jtybFk4oNEZ8VhjWUf5J5LHlN47Y2g81AynP3x4gmiop%2BeovWx5q5193ZqhkNG4WfsLnx5x1%2BdzvOBchHImhTFU3iNd1y1EF9DDNq%2F2f2nZtSL1QB2UKPqlTbrCk1X9m1Ti33etD%2Bx1i2WIkwPB7Fzm3Qr78SU1jWr4FoA2dyJjP3oBqFutmkyOd5tj%2Ft6VpBoZz6GvlBtGwSeQ43Ec6Hf%2BAcyc5mwqTPKJ4gQmHM3eSGa37TAva5ibY%2Bvg15AWuNzthY7waOSxGBk9Fu8Ug%3D%3D--n96Uzyy6RKmuJtCN--zzcV4%2B2xGPwfY7NyQpQvGg%3D%3D; Path=/; HttpOnly; Secure; SameSite=Lax
set-cookie: _octo=GH1.1.273127465.1753910587; Path=/; Domain=github.com; Expires=Thu, 30 Jul 2026 21:23:07 GMT; Secure; SameSite=Lax
set-cookie: logged_in=no; Path=/; Domain=github.com; Expires=Thu, 30 Jul 2026 21:23:07 GMT; HttpOnly; Secure; SameSite=Lax
x-github-request-id: 8426:373DAE:467AD:64B06:688A8D3B
DAO Style Guidelines and Best Practices · apache/superset Wiki · GitHub
Skip to content
Navigation Menu
{{ message }}
-
Notifications
You must be signed in to change notification settings - Fork 15.4k
DAO Style Guidelines and Best Practices
John Bodley edited this page Jun 22, 2023
·
2 revisions
A Data Access Object (DAO) is a pattern that provides an abstract interface to the SQLAlchemy Object Relational Mapper (ORM). The DAOs are critical as they form the building block of the application which are wrapped by the associated commands and RESTful API endpoints.
Currently there are numerous inconsistencies and violation of the DRY principal within the codebase as it relates to DAOs and ORMs—unnecessary commits, non-ACID transactions, etc.—which makes the code unnecessarily complex and convoluted. Addressing the underlying issues with the DAOs should help simplify the downstream operations and improve the developer experience.
To ensure consistency the following rules should be adhered to:
- All database operations (including testing) should be defined within a DAO, i.e., there should not be any explicit
db.session.add
,db.session.merge
, etc. calls outside of a DAO. - A DAO should use
create
,update
,delete
,upsert
terms—typical database operations which ensure consistency with commands—rather than action based terms likesave
,saveas
,override
, etc. - Sessions should be managed via a context manager which auto-commits on success and rolls back on failure, i.e., there should be no explicit
db.session.commit
ordb.session.rollback
calls within the DAO. - There should be a single atomic transaction representing the entirety of the operation, i.e., when creating a dataset with associated columns and metrics either all the changes succeed when the transaction is committed, or all the changes are undone when the transaction is rolled back. SQLAlchemy supports nested transactions via the
begin_nested
method which can be nested—inline with how DAOs are invoked. - The database layer should adopt a "shift left" mentality i.e., uniqueness/foreign key constraints, relationships, cascades, etc. should all be defined in the underlying database schema where possible. Note there are times where this isn’t possible, i.e., MySQL and PostgreSQL treat
NULL
values differently from a uniqueness perspective. If modeled correctly the ORM should implicitly delete all associations and thus one should not need to preemptively undefine relationships, etc. - Avoid validation logic, i.e., ask for forgiveness rather than permission. This is akin to a try/except block where the exception is the exception rather than the rule. Thus instead of first checking whether something is defined before adding, simply try adding it (and per 5) and rely on the database to verify whether the model is acceptable. This removes potential race conditions, reduces the number of database operations, and reduces the code footprint.
- Provide bulk create, update, delete, etc. methods (if possible) for performance reasons.
- By default updates should be sparse in nature, i.e., only those attributes which are explicitly defined are updated.
- Tests should leverage nested transactions which should be rolled back on teardown. This is cleaner than deleting objects. See here for details.
You can’t perform that action at this time.