diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index e2709d676..a34a93708 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -29,6 +29,10 @@ updates:
directory: "/src/test/nodejs/node-postgres"
schedule:
interval: "daily"
+ - package-ecosystem: "npm"
+ directory: "/src/test/nodejs/sequelize-tests"
+ schedule:
+ interval: "daily"
- package-ecosystem: "npm"
directory: "/src/test/nodejs/typeorm/data-test"
schedule:
@@ -74,7 +78,13 @@ updates:
directory: "/samples/java/spring-data-jpa"
schedule:
interval: "daily"
-
+
+ # Node.js samples
+ - package-ecosystem: "npm"
+ directory: "/samples/nodejs/sequelize"
+ schedule:
+ interval: "daily"
+
# Python Samples
# Python psycopg3 Sample
- package-ecosystem: "pip"
diff --git a/.github/workflows/samples.yaml b/.github/workflows/samples.yaml
index 75aac7a6c..5c0f3bcda 100644
--- a/.github/workflows/samples.yaml
+++ b/.github/workflows/samples.yaml
@@ -73,6 +73,11 @@ jobs:
run: |
npm install
npm start
+ - name: Run Sequelize Sample tests
+ working-directory: ./samples/nodejs/sequelize
+ run: |
+ npm install
+ npm start
ruby-samples:
runs-on: ubuntu-latest
steps:
diff --git a/.gitignore b/.gitignore
index f0d25a99a..dbe8c704c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,6 +30,7 @@ samples/nodejs/**/.DS_Store
samples/cloud-run/nodejs/**/node_modules
samples/cloud-run/nodejs/**/package-lock.json
samples/cloud-run/nodejs/**/.DS_Store
+samples/nodejs/sequelize/**/*.js
src/test/ruby/**/Gemfile.lock
samples/**/ruby/**/Gemfile.lock
diff --git a/README.md b/README.md
index 50183d95c..f49228f0e 100644
--- a/README.md
+++ b/README.md
@@ -41,6 +41,8 @@ PGAdapter can be used with the following frameworks and tools:
carefully for how to set up ActiveRecord to work with PGAdapter.
1. `Knex.js` query builder can be used with PGAdapter. See [Knex.js sample application](samples/nodejs/knex)
for a sample application.
+1. `Sequelize.js` ORM can be used with PGAdapter. See [Sequelize.js sample application](samples/nodejs/sequelize)
+ for a sample application.
## FAQ
See [Frequently Asked Questions](docs/faq.md) for answers to frequently asked questions.
diff --git a/samples/nodejs/sequelize/README.md b/samples/nodejs/sequelize/README.md
new file mode 100644
index 000000000..1f9879556
--- /dev/null
+++ b/samples/nodejs/sequelize/README.md
@@ -0,0 +1,17 @@
+
+
+# PGAdapter Spanner and Sequelize
+
+PGAdapter has experimental support for [Sequelize](https://sequelize.org/) with the standard Node.js
+`pg` driver. This sample application shows how to connect to PGAdapter with Sequelize, and how to
+execute queries and transactions on Cloud Spanner.
+
+The sample uses the Cloud Spanner emulator. You can run the sample on the emulator with this
+command:
+
+```shell
+npm start
+```
+
+PGAdapter and the emulator are started in a Docker test container by the sample application.
+Docker is therefore required to be installed on your system to run this sample.
diff --git a/samples/nodejs/sequelize/models/models.ts b/samples/nodejs/sequelize/models/models.ts
new file mode 100644
index 000000000..4fc43dcd8
--- /dev/null
+++ b/samples/nodejs/sequelize/models/models.ts
@@ -0,0 +1,264 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {
+ CreationOptional,
+ DataTypes,
+ HasManyAddAssociationMixin,
+ HasManyGetAssociationsMixin,
+ HasOneGetAssociationMixin,
+ HasOneSetAssociationMixin,
+ InferAttributes,
+ InferCreationAttributes,
+ Model,
+ Sequelize
+} from 'sequelize';
+
+export class Singer extends Model, InferCreationAttributes> {
+ declare id: number;
+ declare firstName: string;
+ declare lastName: string;
+ declare fullName: string;
+ declare active: boolean;
+ declare createdAt: CreationOptional;
+ declare updatedAt: CreationOptional;
+
+ declare getAlbums: HasManyGetAssociationsMixin;
+}
+
+export class Album extends Model, InferCreationAttributes> {
+ declare id: number;
+ declare title: string;
+ declare SingerId: number;
+ declare marketingBudget: number;
+ declare createdAt: CreationOptional;
+ declare updatedAt: CreationOptional;
+
+ declare getSinger: HasOneGetAssociationMixin;
+ declare setSinger: HasOneSetAssociationMixin;
+ declare getTracks: HasManyGetAssociationsMixin