thank you for your time and patience. Again the hints were very useful. The dialect I am implementing is syntactically very similar to Oracle (this was done on purpose) but the semantics are quite different. For example, schema changing operations are transactional. Thus, a rollback will also rollback a table create.
Am Dienstag, 29. Januar 2013 00:09:13 UTC+1 schrieb Michael Bayer: > > > On Jan 28, 2013, at 4:54 PM, jank wrote: > > On implementing a new dialect I am running into lots of issues. All caught > by test cases part of the standard test suite - so thanks for this! > > I have an issue with a reserved word being used as column name: data. > > The test case HasTableTest.test_has_table creates a table using: > > Table('test_table', metadata, > Column('id', Integer, primary_key=True), > Column('data', String(50)) > ) > > A few things are suspicious. Running the resulting create statement on the > DB console I get an error. However, I do not see any error on test > execution, but only the message that the table does not exist: > > Error emptying table test_table: ProgrammingError("(ProgrammingError) > ('42000', '[42000] [EXASOL][EXASolution driver]object TEST_TABLE not found > [line 1, column 13] (-1) (SQLExecDirectW)')",) > ERROR > > I would have expected an error on CREATE TABLE. > > > running the tests with --log-debug=sqlalchemy.engine will help to see all > the SQL being emitted. The "not found" seems like your has_table() > function might not be working. > My has_table() function does indeed has a problem. EXASol does not have a default schema, but not selecting a schema can cause unwanted results. Thus I have decided to make 'SYS' the default schema for the dialect and I do expect that every user of the dialect passes a non None schema. The test cases is not consistently passing the schema name. Again, recommendations on what is expected of a dialect would be useful. I would prefer to always have a schema name passed. Otherwise schema reflection functions like has_table() return unwanted results (as tables with the same name can exist in two different schemas). Is that a valid pre-condition for a dialect? Is the test suite expected to pass the schema name in all test cases? > > I also added 'data' to the list of reserved_words > > > OK, make sure you use the latest default as of yesterday as I just had to > change that test so that it quotes the "data" term, apparently it is > reserved on DB2 as well. > > > and added a _bindparam_requires_quotes method similar to the Oracle > dialect. > > > that's a very unusual setting and unless exaDB is extremely similar to > Oracle it's unlikely you need it. what this means is that if you have a > statement like this: > > INSERT INTO sometable (somecol) VALUES (:data) > > above, we've named a bound parameter with the name "data". Because it is > syntaxed like a bound parameter, it's very unusual that a database client > API would choke on the fact that "data" is a reserved word. But Oracle OCI > does choke on this, so it wants this: > > INSERT INTO sometable (somecol) VALUES (":data") > > the logic to get the quotes in there on a bound parameter, while still > keeping the name of the parameter as "data" without the quotes, is very > awkward but that's what _bindparam_requires_quotes does. This is not > usually what's needed for quoting of reserved words. > I'll check. As the dialect is very similar to Oracle it might require the same qouting, but I am not sure. > > Usually, quoting of reserved words means that a statement like this: > > INSERT into sometable (data) VALUES (:param) > > should instead be rendered like this, because "data" is reserved: > > INSERT into sometable ("data") VALUES (:param) > > All dialects will do this automatically assuming "data" is in the reserved > words registered with the IdentifierPreparer. > > > > But I am not sure if, how and when this set is being used. When running > the test suite I do not see any prints I have added to check if my code is > being executed (but adding syntax errors cause the expected error). So far > I have not understood the test suite magic. > > Any help on understanding the test suite magic or how reserved words are > being used is greatly appreciated. > > > my guess is based on the error message: > > object TEST_TABLE not found > > > the fact that the table name is being reported as UPPERCASE suggests that > this database may store and report on case insensitive names as UPPERCASE. > In SQLAlchemy, an all lower case name is considered to be case > insensitive. So when performing table inspection, an all lower case name > on the SQLAlchemy side must be "normalized" and "denormalized" as it is > passed to the database for schema inspection functions. The Oracle > dialect includes this behavior, as does the Firebird dialect as well as the > DB2 dialect I've been working on. To enable it looks like this (you can > copy this from oracle/base.py): > > > class MyDialect(default.DefaultDialect): > # ... > > requires_name_normalize = True > > def normalize_name(self, name): > if name is None: > return None > # Py2K > if isinstance(name, str): > name = name.decode(self.encoding) > # end Py2K > if name.upper() == name and \ > not self.identifier_preparer._requires_quotes(name.lower()): > return name.lower() > else: > return name > > def denormalize_name(self, name): > if name is None: > return None > elif name.lower() == name and not > self.identifier_preparer._requires_quotes(name.lower()): > name = name.upper() > # Py2K > if not self.supports_unicode_binds: > name = name.encode(self.encoding) > else: > name = unicode(name) > # end Py2K > return name > > you'll then want to call upon denormalize_name() as you query the > databases information schema for tables, schemas and columns - you can see > this in Oracle's has_table() method. > > this is again just a hunch based on that UPPERCASE name in your error > message. Running with --log-debug=sqlalchemy.engine will show all queries > being emitted as well as results. I'd recommend running tests > individually when that setting is enabled. > > > > -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy?hl=en. For more options, visit https://groups.google.com/groups/opt_out.