I am trying to get this setup to work, the database is created correctly, but trying to insert data I get the following error:
On sqlite:
sqlalchemy.exc.OperationalError
OperationalError: (sqlite3.OperationalError) no such column: Author [SQL: u'SELECT count(*) AS count_1 \nFROM (SELECT Author) AS anon_1']
On postgres:
sqlalchemy.exc.ProgrammingError
ProgrammingError: (psycopg2.ProgrammingError) column "author" does not exist
LINE 2: FROM (SELECT Author) AS anon_1
^
[SQL: 'SELECT count(*) AS count_1 \nFROM (SELECT Author) AS anon_1']
edit: Perhaps this has to do with it: I don't understand why it says "anon_1", as I am using credentials clearly?
I have inspected postgres and sqlite and the tables are created correctly. It seems to be an ORM configuration error, as it only seems to happend on inspecting or creating entries, any suggestion would be welcome!
class Author(CommonColumns):
__tablename__ = 'author'
author = Column(String(200))
author_url = Column(String(2000))
author_icon = Column(String(2000))
comment = Column(String(5000))
registerSchema('author')(Author)
SETTINGS = {
'SQLALCHEMY_TRACK_MODIFICATIONS': True,
'SQLALCHEMY_DATABASE_URI': 'sqlite:////tmp/test.db',
# 'SQLALCHEMY_DATABASE_URI': 'postgresql://xxx:xxx#localhost/test',
}
application = Flask(__name__)
# bind SQLAlchemy
db = application.data.driver
Base.metadata.bind = db.engine
db.Model = Base
db.create_all()
if __name__ == "__main__":
application.run(debug=True)
What is the query you're using to insert data?
I think the error messages may be a bit more opaque than they need to be because you're using Author/author in three very similar contexts:
the Class name
the table name
the column name
For easier debugging, the first thing I'd do is temporarily make each one unique (AuthorClass, author_table, author_column) so you can check which 'Author' is actually being referred to by the error message.
Since you're using the ORM, I suspect the underlying issue is that your insert statement uses Author (the object) when it should actually be using Author.author (the attribute/column name). The SELECT statements are complaining that they can't find the column 'author', but because you use author for both the table and column name, it's unclear what's actually being passed into the SQL statement.
Related
I got table like this:
class ReportImages(Base):
__tablename__ = 'very_long_name_of_table'
id = Column('long_column_name', Integer, primary_key=True)
And i run select from Oracle Database it raises exception:
sqlalchemy.exc.DatabaseError: (cx_Oracle.DatabaseError) ORA-00972: identifier is too long
[SQL: SELECT very_long_name_of_table.long_column_name AS very_long_name_of_table_long_column_name FROM very_long_name_of_table]
How can is set my own alias for select or not to use column aliases at all?
Select like
data = session.query(ReportImages).all()
Solved it with setting alias before query:
ri = aliased(ReportImages, name='ri')
data = session.query(ri)
It works, but still interesting how i can set label styling in ReportImages class.
I have a problem to use flask_alchemy for my unit test function
In the production environment I use a postgresql database
"SQLALCHEMY_DATABASE_URI": "postgresql://login:passwd#dburl:1234/mydatabase",
To work with the postgresql schema, in my entity definition i declare a _table_args to specify a schema
class MyTable(Base):
__tablename__ = 'my_tablename'
__table_args__ = {'schema': 'mydbschema'}
my_id = Column('my_id', Date, primary_key=True)
....
But in my unittest i would like to use a memory database
"SQLALCHEMY_DATABASE_URI": "sqlite://",
When i run my function i have this error :
E sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) unknown database "mydbschema"
Somebody knows a workarround in this case ?
I know that OP found a workaround (though, I'm not sure how it works), but for those who still searching for proper solution - you need to use ATTACH DATABASE statement in order to select specific schema, for example if you are using pytest you can use following fixture to create test's setup:
from sqlalchemy import create_engine
#pytest.fixture
def setup_db():
engine = create_engine('sqlite:///:memory:')
with engine.connect() as conn:
conn.execute('ATTACH DATABASE \':memory:\' AS mydbschema;')
yield conn
Of course, you can define fixture scope by your needs.
Similarly, you can use DETACH DATABASE statement to detach and dissociate a named database from a database connection (if necessary), which will destroy DB in the case of in-memory databases.
I found a workaround ...
class MyTable(Base):
__tablename__ = 'my_tablename'
__table_args__ = {'schema': 'mydbschema'}
my_id = Column('my_id', Date, primary_key=True) if os.environ.get('TESTVAR') is None else {}
....
I am creating MySQL tables dynamically with the following code SQL Alchemy code:
meta = Base.metadata
table_data = Table(
table_name, meta,
Column('id', Integer, primary_key=True, nullable=False),
Column('file_name', String(250), nullable=False))
)
meta.create_all(engine, [table_data])
The table_name variable is a unique string sent via an API POST call. The problem is that the table name can contain special characters, which I cannot change.
If I try to manually create the name via MySQL workbench, it works fine. But it will throw an error when I do it via SQL Alchemy. Can anybody advise how to make it work? Any help is appreciated.
Thanks!
EDIT:
Here is an example, with the error for name data_E82sR4g5YtXqv#AT2QIwH4bQ==:
(MySQLdb._exceptions.ProgrammingError) (1064, '')
[SQL: drop table if exists data_E82sR4g5YtXqv#AT2QIwH4bQ==]
(Background on this error at: http://sqlalche.me/e/f405)
I'm currently going over a course in Web design. What I want to do is to check if a table named portafolio exists in my database, if not I want to create one.
I'm using Python (flask) and sqlite3 to manage my database.
So far I the some of the logic in SQL to create a table if it doesn't exist:
# db is my database variable
db.execute('''create table if not exists portafolio(id INTEGER PRIMARY KEY AUTOINCREMENT,
stock TEXT,
shares INTEGER,
price FLOAT(2),
date TEXT
''');
But instead of using SQL commands I'd like to know how would I do the exact same checking in Python instead, since it would look a lot cleaner.
Any help would be appreciated.
Not sure about which way is cleaner but you can issue a simple select and handle the exception:
try:
cursor.execute("SELECT 1 FROM portafolio LIMIT 1;")
exists = True
except sqlite3.OperationalError as e:
message = e.args[0]
if message.startswith("no such table"):
print("Table 'portafolio' does not exist")
exists = False
else:
raise
Note that here we have to check what kind of OperationalError it is and, we have to have this "not pretty" message substring in a string check because there is currently no way to get the actual error code.
Or, a more SQLite specific approach:
table_name = "portafolio"
cursor.execute("""
SELECT name
FROM sqlite_master
WHERE type='table' AND name=?;
""", (table_name, ))
exists = bool(cursor.fetchone())
If you are looking for a neat job with Database operations, I advice you learn more about ORM(Object Relation Model).
I use Flask with SQLAlchemy. You can use python classes to manage SQL operations like this:
class Portafolio(db.Model):
id = db.Column(db.Integer, primary_key=True)
stock = db.Column(db.String(255), unique=True)
shares = db.Column(db.Integer, unique=True)
It does all the database checks and migration easily.
I am trying to access pre-created MySQL View in the database via. peewee treating it as a table [peewee.model], however I am still prompted with Operational Error 1054 unknown column.
Does PeeWee Supports interactions with database view ?
Peewee has been able to query against views when I've tried it, but while typing up a simple proof-of-concept I ran into two potential gotcha's.
First, the code:
from peewee import *
db = SqliteDatabase(':memory:')
class Foo(Model):
name = TextField()
class Meta: database = db
db.create_tables([Foo])
for name in ('huey', 'mickey', 'zaizee'):
Foo.create(name=name)
OK -- nothing exciting, just loaded three names into a table. Then I made a view that corresponds to the upper-case conversion of the name:
db.execute_sql('CREATE VIEW foo_view AS SELECT UPPER(name) FROM foo')
I then tried the following, which failed:
class FooView(Foo):
class Meta:
db_table = 'foo_view'
print [fv.name for fv in FooView.select()]
Then I ran into the first issue.
When I subclassed "Foo", I brought along a primary key column named "id". Since I used a bare select() (FooView.select()), peewee assumed i wasnted both the "id" and the "name". Since the view has no "id", I got an error.
I tried again, specifying only the name:
print [fv.name for fv in FooView.select(FooView.name)]
This also failed.
The reason this second query fails can be found by looking at the cursor description on a bare select:
curs = db.execute_sql('select * from foo_view')
print curs.description[0][0] # Print the first column's name.
# prints UPPER(name)
SQLite named the view's column "UPPER(name)". To fix this, I redefined the view:
db.execute_sql('CREATE VIEW foo_view AS SELECT UPPER(name) AS name FROM foo')
Now, when I query the view it works just fine:
print [x.name for x in FooView.select(FooView.name)]
# prints ['HUEY', 'MICKEY', 'ZAIZEE']
Hope that helps.