Manually initializing a destroyed connection pool did not change database schema name
See original GitHub issueSummary
I am setting up test script to create multiple database schema to utilize AVA parallel test run. As a result, I need to create the schema first, then switch the application connection pool to use the new created schema. However I encountered a bug in doing so, and would like to ask the official proper way to change the database schema name.
Environment
Knex version: 0.21.0 Database + version: MySQL 5.7 OS: Windows 10
Bug
According to the documentation:
If you ever need to explicitly teardown the connection pool, you may use
knex.destroy([callback])
. You may useknex.destroy
by passing a callback, or by chaining as a promise, just not both. To manually initialize a destroyed connection pool, you may useknex.initialize([config])
, if no config is passed, it will use the first knex configuration used.
I expect I can change the database name by knex.destroy
and knex.initialize(newConfig)
with new configuration. This does not work.
Reduced test case as follows:
const knex = require('knex')
function getConfig () {
return {
client: 'mysql',
connection: {
host: 'localhost',
user: 'root',
password: ''
}
}
}
const db = knex(getConfig()).on('query', function (data) {
console.log(data.sql)
})
const method = 1
;(async () => {
// Randomly (in my case it is based on server listening port) assigned a database name for AVA parallel testing
const dbName = 'TMP_DB_' + (Math.floor(Math.random() * 999) + 9001)
try {
await db.raw(`CREATE DATABASE ${dbName}`)
await db.raw(`USE ${dbName}`)
await db.schema.createTable('tmp1', (table) => {
table.increments()
table.string('val1', 10).notNullable()
})
if (method === 1) {
// I tried the documented way, but the `connection.database` is not changed with the following code
await db.destroy()
const newConfig = getConfig()
newConfig.connection.database = dbName
db.initialize(newConfig)
} else if (method === 2) {
// Is this the proper way to set the `connection.database`?
db.client.connectionSettings.database = dbName
}
// This will result in `Error: ER_NO_DB_ERROR: No database selected` if database name is not set
await Promise.all([
db('tmp1').insert({ val1: 'a' }),
db('tmp1').insert({ val1: 'b' }),
db('tmp1').insert({ val1: 'c' })
])
} finally {
try {
await db.raw(`DROP DATABASE ${dbName}`)
} catch (ignore) {}
await db.destroy()
}
console.log('End')
})().catch(e => console.log(e.stack))
Question
My additional question together with this bug, is how to change the database schema of the connection pool? Is the const method = 2
the proper way to do so? Or it can only be treated as undocumented way and may change in the future?
Issue Analytics
- State:
- Created 3 years ago
- Comments:10 (2 by maintainers)
@MehdiSaffar I haven’t thought of using
Proxy
at that time (maybe I didn’t even knowProxy
at that time). Thanks a lot for sharing, though I am no longer working with project using RDBMS now.@VeryCrazyDog Here is a temporary approach with ES6 proxies you could use if you want, not sure how correct it is but it seems to work on my side. Example: